题解:首先,是一棵树的话要满足的条件是
1 不成环;
2 除了根,所有的入度为1,根入度为0;
3 只有一棵树,不是森林
那么,用并查集记录父亲,如果矛盾就成环,而最后找到一个节点的父亲,如果其余的不是则为森林,而入度则在开始时记一下,最后发现如果有入度大于1的则也不行。
#include <cstdio> #include <iostream> using namespace std; const int MAXN=100010; int f[MAXN],flag,hash[MAXN],in[MAXN]; void init(){ flag=1; for(int i=1;i<MAXN;i++){f[i]=i;in[i]=0;hash[i]=0;} } int sf(int x){ if(x!=f[x])f[x]=sf(f[x]); return f[x]; } int main(){ int cnt=1,root,x,y; init(); while(scanf("%d%d",&x,&y)){ if(x<0&&y<0)break; if(x==0&&y==0){ if(flag){ for(int i=1;i<MAXN;i++){if(hash[i]){root=sf(i);break;}} for(int i=1;i<MAXN;i++){ if(in[i]>1){flag=0;break;} if(hash[i]&&root!=sf(i)){flag=0;break;} } } if(flag)printf("Case %d is a tree. ",cnt++); else printf("Case %d is not a tree. ",cnt++); init(); }else{ if(sf(x)==sf(y))flag=0; if(!flag)continue; hash[x]=hash[y]=1; in[x]++; f[sf(x)]=sf(y); } } }