题目:
中文的~~~~
思路:
属于并查集算法,输出YES的条件有两个,第一:每次新输入的两个数不能同属于一个集合(即根节点一样),第二:所有的输入完成后判断是否仅有一个集合(根节点只有一个)。只有这两个条件全部达成,才能输出“YES”~~~需要注意的是 直接输入“0 0”,应该输出“YES”。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cmath> 6 #include <cctype> 7 #include <algorithm> 8 using namespace std; 9 const int MAXN = 1e5 + 3; 10 int pre[MAXN]; 11 bool bol[MAXN]; 12 int maxn = -1; 13 int flag = 1; //标记是否出现了根节点一样的两个点、即条件一、默认是没有出现 14 15 int Find(int x) 16 { 17 int r = x; 18 while(pre[r] != r) 19 { 20 r = pre[r]; 21 } 22 int i = x,j; 23 while(pre[i] != r) 24 { 25 j = i; 26 i = pre[i]; 27 pre[j] = r; 28 } 29 return r; 30 } 31 32 void Mix(int a,int b) 33 { 34 int x = Find(a); 35 int y = Find(b); 36 if(x > y) 37 { 38 pre[x] = y; 39 } 40 if(x < y) 41 { 42 pre[y] = x; 43 } 44 } 45 46 void Mst() //初始化 47 { 48 maxn = -1; 49 flag = 1; 50 for(int i = 1; i <= MAXN; i++) 51 { 52 pre[i] = i; 53 bol[i] = false; 54 } 55 } 56 57 int Search(int maxn) //计算集合的个数 58 { 59 int cnt = 0; 60 for(int i = 1; i <= maxn; i++) 61 { 62 if(bol[i]) 63 if(pre[i] == i) 64 cnt++; 65 } 66 if(maxn <= 0) 67 return 1; 68 return cnt; 69 } 70 71 int main() 72 { 73 int M,N; 74 Mst(); 75 while(~scanf("%d%d",&M,&N)&&(M != -1 || N != -1)) 76 { 77 maxn = max(max(M,N),maxn); 78 bol[M] = true; //这个点出现过 79 bol[N] = true; 80 if(M||N) 81 { 82 int m = Find(M); 83 int n = Find(N); 84 if(flag && m == n) 85 flag = 0; //不满足条件一 86 else 87 Mix(m,n); 88 } 89 else 90 { 91 int single = Search(maxn); //是否只有一个根节点 92 if(single== 1 && flag) printf("Yes "); //两个条件都满足 93 else printf("No "); 94 Mst();//注意数据初始化 95 } 96 } 97 return 0; 98 }