额, 这题怎么说呢,一开始觉得很难,可是看了别人的思路之后,觉得还可以吧
判定是否为树:
1):每个节点的入度为0或1
2):只有一个根节点
3):不构成环
其他的,在代码中已经有解释了
#include<stdio.h> #define MAXN 1010 int f[MAXN], r[MAXN],k[MAXN]; //f[]记录该节点的父节点,r[]记录该节点的子节点个数,k[]记录该节点是否出现过 int find(int x) { if(x!=f[x]) f[x]=find(f[x]); return f[x]; }//查找父节点,路径压缩,其实,在这里已经把子节点都连接到根节点上了 int dec() { int i,t; for(i=1;i<MAXN;i++) if(k[i]) ++r[find(i)];//累加对应根节点的子节点个数 t=0; for(i=1;i<MAXN;i++) if(r[i]>1)//判定根节点个数 t++; if(t>1)//判定为树还是森林 return 0; else return 1; } int main() { int i,c=0,x,y,a,b; while(1) { int flag=0; for(i=1;i<MAXN;i++) { f[i]=i; r[i]=0;k[i]=0; } while(scanf("%d %d",&a,&b)) { if((a==0&&b==0)||a<0) break; x=find(a);y=find(b); k[a]=k[b]=1; if(x==y||b!=y)//根节点相同则构成环,b!=y,则说明b已经有一个父节点了,即b的入度为2 flag=1; else f[b]=a; } if(a<0) break; if(flag) printf("Case %d is not a tree.\n",++c); else { if(dec()) printf("Case %d is a tree.\n",++c); else printf("Case %d is not a tree.\n",++c); } } return 0; }