6 8 5 3 5 2 6 4 5 6 0 0 8 1 7 3 6 2 8 9 7 5 7 4 7 8 7 6 0 0 3 8 6 8 6 4 5 3 5 6 5 2 0 0 -1 -1
Yes Yes No
并查集若检测出环则直接NO,否则还要判断是否是森林,若是则no;
#include <stdio.h> #include <string.h> int pre[100002]; bool flag[100002]; int find(int k){ if(pre[k] == 0) return k; int i = k; while(pre[i] != 0) i = pre[i]; int j = k, t; while(pre[j] != 0){ t = pre[j]; pre[j] = i; j = t; } return i; } int main(){ int a, b, ok = 1, x, y, mark; while(scanf("%d%d", &a, &b)){ if(a == -1 && b == -1) break; if(a == 0 && b == 0){ if(ok == 0) printf("No\n"); else{ mark = find(mark); for(int i = 1; i < 100001; ++i){ if(flag[i] && mark != find(i)){ ok = 0; break; } } printf(ok ? "Yes\n" : "No\n"); } ok = 1; memset(pre, 0, sizeof(pre)); memset(flag, 0, sizeof(flag)); continue; } if(ok == 0) continue; mark = x = find(a); y = find(b); flag[a] = flag[b] = 1; if(x == y) ok = 0; else mark = pre[x] = y; } return 0; }
2014.11.25更新
#include <stdio.h> #include <string.h> #define maxn 100005 int pre[maxn]; bool vis[maxn]; int ufind(int k) { int a = k, b; while(pre[k] != -1) k = pre[k]; while(a != k) { b = pre[a]; pre[a] = k; a = b; } return k; } bool unite(int x, int y) { x = ufind(x); y = ufind(y); if(x == y) return false; pre[x] = y; return true; } int main() { // freopen("stdin.txt", "r", stdin); int i, j, cnt = 0, x, y, ok = 1; memset(pre, -1, sizeof(pre)); memset(vis, 0, sizeof(vis)); while(scanf("%d%d", &x, &y), x >= 0) { if(x == 0) { if(cnt > 1) ok = 0; printf(ok ? "Yes\n" : "No\n"); ok = 1; cnt = 0; memset(pre, -1, sizeof(pre)); memset(vis, 0, sizeof(vis)); continue; } if(ok == 0) continue; if(!vis[x]) { vis[x] = 1; ++cnt; } if(!vis[y]) { vis[y] = 1; ++cnt; } if(!unite(x, y)) ok = 0; else --cnt; } return 0; }