标签:并查集
| Time Limit: 1000MS | Memory Limit: 10000K | |
| Total Submissions: 22631 | Accepted: 7756 | 
Description

Input
Output
Sample Input
6 8 5 3 5 2 6 4 5 6 0 0 8 1 7 3 6 2 8 9 7 5 7 4 7 8 7 6 0 0 3 8 6 8 6 4 5 3 5 6 5 2 0 0 -1 -1
Sample Output
Case 1 is a tree. Case 2 is a tree. Case 3 is not a tree.
Source
判断一些点形成的结构是否是一棵树,坑点好多,用并查集判断连通支数以及环,判断每个点的入度,判断是否有自己连向自己的边
#include <map>
#include <set>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int father[100010];
bool vis[100010];
int in_deg[100010];
int find(int x)
{
    if (father[x] == -1)
    {
        return x;
    }
    return father[x] = find(father[x]);
}
void init()
{
    memset( father, -1, sizeof(father));
    memset( vis, 0, sizeof(vis));
    memset(in_deg, 0, sizeof(in_deg));
}
int main()
{
    int x, y;
    int icase = 1;
    while (~scanf("%d%d", &x, &y))
    {
        if (x == -1 && y == -1)
        {
            break;
        }
        if (x == 0 && y == 0)
        {
            printf("Case %d is a tree.\n", icase++);
            continue;
        }
        init();
        map<int, int> bianhao;
        bianhao.clear();
        int cnt = 0;
        bool flag = true;
        while (x && y)
        {
            if (!x && !y)
            {
                break;
            }
            if (x == y)
            {
                flag = false;
            }
            if (flag && !vis[x])
            {
                vis[x] = 1;
                bianhao[x] = ++cnt;
            }
            if (flag && !vis[y])
            {
                vis[y] = 1;
                bianhao[y] = ++cnt;
            }
            if (flag)
            {
                int a = find(bianhao[x]);
                int b = find(bianhao[y]);
                if (a == b)
                {
                    flag = false;
                }
                father[a] = b;
                in_deg[bianhao[y]]++;
            }
            scanf("%d%d", &x, &y);
        }
        if (!flag)
        {
            printf("Case %d is not a tree.\n", icase++);
            continue;
        }
        int ans = 0;
        // for (int i = 1; i <= cnt; ++i)
        // {
            // printf("%d ", in_deg[i]);
        // }
        for (int i = 1; i <= cnt; ++i)
        {
            if (in_deg[i] == 0)
            {
                ans++;
            }
            if (ans >= 2)
            {
                break;
            }
            if (in_deg[i] >= 2)
            {
                flag = false;
                break;
            }
        }
        if (ans >= 2 || !flag)
        {
            printf("Case %d is not a tree.\n", icase++);
            continue;
        }
        printf("Case %d is a tree.\n", icase++);
    }
    return 0;
}
标签:并查集
原文地址:http://blog.csdn.net/guard_mine/article/details/41318859