(并查集)POJ 1308 & HDU 1325

一开始以为两道题是一样的,POJ的过了直接用相同代码把HDU的交了,结果就悲剧了。最后发现HDU的没有考虑入度不能大于一。

题意:用树的定义来 判断吧,无环,n个结点最多有n-1条边,不然就会有环。只有一个入度为0的结点,不存在入度大于1的结点。

思路:并查集.

AC代码:

#include<stdio.h>
#include<string.h>
#define N 100005
int in[N],pre[N],a,b,c[N];
void init()//初始化
{
    for(int i=0;i<=100000;i++)
        {
            in[i]=0;
            c[i]=0;
            pre[i]=i;
        }
}
int find(int x)//路径压缩,提高效率
{
    if(x != pre[x])
        pre[x] = find(pre[x]);
    return pre[x];
}
void mix(int x,int y)
{
    x=find(x);
    y=find(y);
    if(x!=y)
    {
        if(x>=y)
            pre[x]=y;
        else
            pre[y]=x;
    }
}
int main()
{
    int flag,i,sum,n=0,qq;
    while(scanf("%d%d",&a,&b)!=EOF)
    {
        if(a<0&&b<0)
            break;
        flag=0;
        qq=1;
        n++;
        init();
        while(a!=0&&b!=0)
        {
            if(find(a)==find(b))//有祖先节点相同的情况,有的话就是存在环,不是树。
                flag=1;
            mix(a,b);
            in[a]=1;
            in[b]=1;
            c[b]++;
            if(c[b]>1)//入度大于一,不是树
                qq=0;
            scanf("%d%d",&a,&b);
        }
        if(flag==1||qq==0)
            printf("Case %d is not a tree.\n",n);
        else
        {
            sum=0;
            for(i=0;i<=100000;i++)
                if(in[i]&&pre[i]==i)
                    sum++;
            if(sum > 1)//多个树根,不是树,是森林
                printf("Case %d is not a tree.\n",n);
            else
                printf("Case %d is a tree.\n",n);
        }
    }
    return 0;
}

  

posted @ 2014-07-16 16:21  PJQOOO  阅读(257)  评论(3编辑  收藏  举报