hdu 小希的迷宫
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1272
这是一个并查集题,看似很水,其实陷阱也有很多,尤其是有了垃圾数据0 0,- -
注意几个地方:(1)0 0输出Yes;(2),可能不是连通图,所以要判断是否连通,不连通No;(3),可能不是每个点都出现,比如最大点4,只出现了1 2 4,所以要注意标记。
#include <stdio.h> #include <string.h> #include <algorithm> #include <string> #include <iostream> using namespace std; #define N 100005 int p[N], r[N], v[N]; bool ans[N]; void makeset(int n){ for (int i = 1; i <= n; i++){ p[i] = i; r[i] = 0; ans[i] = false; } } int findset(int x){ if (x != p[x]) p[x] = findset(p[x]); return p[x]; } void unionset(int x , int y){ x = findset(x); y = findset(y); if (r[x] > r[y])p[y] = x; else { p[x] = y; if (r[x] == r[y])r[y]++; } } int main() { int a, b; while (scanf("%d%d", &a, &b) != EOF) { if (a == -1 && b == -1)break; //有垃圾数据0 0 if (!a && !b){ cout<<"Yes"<<endl; continue; } makeset(N - 3); int m = max(a, b); bool flag = false; unionset(a, b); //标记已经出现 ans[a] = ans[b] = true; while (scanf("%d%d", &a, &b) && (a || b)) { //判断是否有环 if (findset(a) == findset(b)) flag = true; else { unionset(a, b); } m = max(m, max(a, b)); ans[a] = ans[b] = true; } //判断根节点是否唯一 int temp = -1; for (int i = 1; i <= m; i++){ if (ans[i]){ if (temp == -1)temp = findset(i); else if (temp != findset(i)) { flag = true; break; } } } if (flag)cout<<"No"<<endl; else cout<<"Yes"<<endl; } return 0; }