POJ 1308/并查集

题目链接

/*
判断一棵树:
* 1、There is exactly one node, called the root, to which no directed edges point. 
* 2、Every node except the root has exactly one edge pointing to it. 
* 3、There is a unique sequence of directed edges from the root to each node. 
并查集应用
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=10000+5;
int f[maxn];
bool vis[maxn];
bool flag;
int a,b;
int r1,r2;
int ma;
void init()
{
    memset(vis, false, sizeof(vis));
    for(int i=0;i<maxn;i++)
        f[i]=i;
    ma=0;
    flag=true;
}
int find(int t)//并查集
{
    if(f[t]!=t)
        return f[t]=find(f[t]);
    else
        return f[t];
}
int main ()
{
    int k=0;
    init();
    while(~scanf("%d%d",&a,&b))//a->b
    {
        if(a<0||b<0)
            break;
        ma=max(ma,max(a,b));
        vis[a]=vis[b]=true;
        if(a==0&&b==0)
        {
            if(!flag)
                printf("Case %d is not a tree.\n",++k);
            else
            {
                int t=0;
                for(int i=1;i<=ma;i++)
                {
                    if(vis[i]&&f[i]==i)
                        t++;
                }
                if(t>=2)
                    flag=false;
                if(flag)
                    printf("Case %d is a tree.\n",++k);
                else
                    printf("Case %d is not a tree.\n",++k);
            }
            init();
            continue;
        }
        else if(flag)
        {
            r1=find(a);
            r2=find(b);
            if(r1==r2)//
                flag=false;
            else
            {
                if(f[b]==b)//每个节点只能被指向一次
                    f[b]=r1;
                else
                    flag=false;
            }
        }
    }
    return 0;
}
posted @ 2016-08-28 10:02  _Mickey  阅读(115)  评论(0编辑  收藏  举报