13-14寒假作业8

时间:2021-08-19 21:53:15

poj 1308  是不是一颗树?

输入几对数a,b,表示a点指向b点的一条边。判断这些边是否可以组成一颗树。输入两个零表示一组数据结束,输入两个-1表示程序结束。

首先如果是一个树,边数一定是节点数减一,所以首先判断这一点。但是这样还还不够,我们得保证这些边不成环。于是这里可应用到并查集。

然后每输入一条边,都用并查集判断这两个点是否在同一个集合里。如果他们在同一个集合里,就说明出现了环,也就不是一颗树。

还有,直接输入两个0居然也是一颗树- -有点坑啊。。。

 

#include<cstdio>
#include<cstring>
const int maxn=1000;
int x,y,OK,temp;
int f[maxn];
bool u[maxn];
int find(int x)
{
    return x==f[x]?x:f[x]=find(f[x]);
}
int main()
{
    int t=1,i,a1,a2;
    temp=1;
    while(scanf("%d%d",&x,&y),x!=-1&&y!=-1)
    {
        if(temp&&!x&&!y)
        {
            printf("Case %d is a tree.\n",t++);
            continue;
        }
        if(temp)
        {
            a1=a2=0;
            OK=1;
            memset(u,1,sizeof(u));
            for(i=0;i<maxn;++i)
                f[i]=i;
        }
        a2++;
        if(temp) temp=0;
        if(!x&&!y)
        {
            temp=1;
            if(a1!=a2) OK=0;
            OK?printf("Case %d is a tree.\n",t++):printf("Case %d is not a tree.\n",t++);
            continue;
        }
        else
        {
            if(f[y]=find(x)==find(y)) OK=0;
            if(u[x]) {a1++;  u[x]=0;}
            if(u[y]) {a1++;  u[y]=0;}

        }
    }
    return 0;
}