NYOJ-129 并查集
这个题基本上是并查集稍微一变, 只是加了一些判断条件而已,就是将点合并成树, 最后遍历一下, 统计一下有多少棵树, 如果不是1的话, 肯定不是树,所以,可以根据这个来判断
1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 using namespace std; 5 6 const int MAX = 10050; 7 int f[MAX], IN[MAX], k = 0, sum = 0;//IN表示节点的入度 8 bool visit[MAX];/*标记数组中的点是否存在, 就是是否是图中的点, 9 只要是输入的点, 其visit全部为true*/ 10 bool flag;//标记是否是树 11 //初始化 12 void init() 13 { 14 for(int i = 1; i < MAX; i++) 15 f[i] = i; 16 } 17 //找到它的父亲 18 int getf(int i) 19 { 20 if(i != f[i]) 21 { 22 f[i] = getf(f[i]);//路径压缩 23 } 24 return f[i]; 25 } 26 //合并函数, 27 void merge(int i, int j) 28 { 29 int t1 = getf(i); 30 int t2 = getf(j); 31 if(t1 != t2) 32 { 33 f[t2] = t1; 34 } 35 else 36 flag = false;//如果输入的点已经存在 37 } 38 39 int main() 40 { 41 int x, y; 42 flag = true; 43 int max_num = 0; 44 memset(f, 0, sizeof(f)); 45 memset(IN, 0, sizeof(IN)); 46 memset(visit, false, sizeof(visit)); 47 init(); 48 while(scanf("%d %d", &x, &y)) 49 { 50 if(x == -1 && y == -1) 51 break; 52 if(x == 0 && y == 0) 53 { 54 sum = 0; 55 for(int i = 1; i <= max_num; i++) 56 { 57 if(visit[i] && i == f[i])//如果是根节点, 也就是树的个数 58 sum++; 59 } 60 for(int i = 1; i <= max_num; i++) 61 if(visit[i] && IN[i] > 1)//如果一个节点的入度大于1 62 flag = false; 63 if(sum > 1) 64 flag = false; 65 if(flag) 66 printf("Case %d is a tree.\n", ++k); 67 else 68 printf("Case %d is not a tree.\n", ++k); 69 memset(f, 0, sizeof(f)); 70 memset(visit, false, sizeof(visit)); 71 memset(IN, 0, sizeof(IN)); 72 flag = true; 73 init(); 74 } 75 else 76 { 77 if(!flag) 78 continue; 79 max_num = max(max_num, max(x, y)); 80 visit[x] = true;//标记此点在图中 81 visit[y] = true; 82 IN[y]++;//将第二个点的入度加一 83 merge(x, y); 84 } 85 } 86 return 0; 87 }