1.迄今为止做过的最费劲的一道题,到现在思路还不是很清楚;
2.主要考察并查集,并查集的概念(http://www.nocow.cn/index.php/%E5%B9%B6%E6%9F%A5%E9%9B%86)。到目前为止这种思想还没有。
3.并查集的主要操作,找父节点,合并,路径压缩;
4.刚开始WA,把100000改成100010后AC了就
以下是代码:
#include <stdio.h> #include <iostream> using namespace std; int fath[100010], rank[100010], visit[100010]; void initial() { for(int i = 0; i < 100010; i++) { fath[i] = i; rank[i] = 0; visit[i] = 0; } } int find(int x) { return fath[x] == x ? fath[x] : find(fath[x]); } bool unionSet(int x, int y) { int aa = find(x); int bb = find(y); if (aa == bb) return false; if (rank[aa] > rank[bb]) fath[bb] = aa; else { fath[aa] = bb; rank[bb] ++; } return true; } int main() { int a, b,i; while (scanf("%d%d", &a, &b) != EOF && a + b != -2) { if( a + b == 0 ) { cout << "Yes" <<endl; continue; } initial(); unionSet(a, b); visit[a] = visit[b] = 1; int flag = 0; while (scanf("%d%d", &a, &b) && a != 0 && b != 0) { if( !unionSet(a, b) ) flag = 1; visit[a] = visit[b] = 1; } int cnt = 0; for(i = 0; i < 100010; i++) if(visit[i] == 1 && fath[i] == i) cnt ++; if (cnt > 1) flag = 1; if(flag) cout << "No" << endl; else cout << "Yes" << endl; } return 0; }