http://poj.org/problem?id=1308
并查集。1.不能有环,即只能有一个节点的入度为零 2.除根节点外,其余所有结点的入度必需为1 3.空树也是树
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <set> 5 #include <iterator> 6 using namespace std; 7 int father[10002]; 8 int degree[10002]={0}; 9 set<int> V; 10 void init() 11 { 12 int i; 13 for(i=0;i<10002;i++) { 14 father[i]=i; 15 degree[i]=0; 16 } 17 } 18 bool check_one_father(int *f) 19 { 20 int i; 21 int count=0; 22 set<int>::iterator it=V.begin(); 23 while(it!=V.end()) { 24 if(father[*it]==*it) { 25 *f=*it; 26 count++; 27 } 28 it++; 29 } 30 if(count!=1) 31 return false; 32 return true; 33 } 34 bool check_degree(int f) 35 { 36 set<int>::iterator it=V.begin(); 37 while(it!=V.end()) { 38 if(*it==f) { 39 it++; 40 continue; 41 } 42 else if(degree[*it]!=1) 43 return false; 44 it++; 45 } 46 return true; 47 } 48 49 bool judge() 50 { 51 int fa; 52 if(!check_one_father(&fa)) 53 return false; 54 if(degree[fa]!=0) 55 return false; 56 if(!check_degree(fa)) 57 return false; 58 return true; 59 } 60 void join(int fa,int chil) 61 { 62 father[chil]=fa; 63 } 64 int find_father(int chil) 65 { 66 if(father[chil]==chil) return chil; 67 return find_father(father[chil]); 68 } 69 int main() 70 { 71 int k=1; 72 int edge_a,edge_b; 73 V.clear(); 74 init(); 75 while(scanf("%d%d",&edge_a,&edge_b)!=EOF) { 76 if(edge_a==edge_b&&edge_a==-1) 77 return 0; 78 if(edge_a==edge_b&&edge_a==0) { 79 if(V.empty()) printf("Case %d is a tree.\n",k++); 80 else if(judge()) 81 printf("Case %d is a tree.\n",k++); 82 else 83 printf("Case %d is not a tree.\n",k++); 84 init(); 85 V.clear(); 86 } else { 87 int fa=find_father(edge_a); 88 join(fa,edge_b); 89 degree[edge_b]++;//edge_b的入度加1 90 V.insert(edge_a); 91 V.insert(edge_b); 92 } 93 } 94 }