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;
}