本题要求给定的无向图,判断所给图是不是连通的,并且图中不存在回路,用并查集判断是否存在回路,当某条边的两个节点有共同的父节点时说明图中存在回路,在判断图是不是连通只要判断所有的节点的父节点是否只有一个。 /* Author: ACb0y Date: 2010-10-17 ProblemId: hdu 1272 小希的迷宫 Type: union set Result: 3082681 2010-10-17 22:40:53 Accepted 1272 78MS 3492K 1530 B G++ ACb0y */ #include <iostream> #include <vector> #include <set> using namespace std; struct edge { int u; int v; }; int father[100010]; int find_father(int a) { if (father[a] == 0) { return a; } else { int temp = find_father(father[a]); father[a] = temp; return father[a]; } } void union_set(int a, int b) { father[a] = b; } int main() { int a, b; vector<edge> v; set<int> s; memset(father, 0, sizeof(father)); #ifndef ONLINE_JUDGE freopen("1272.txt", "r", stdin); #endif while (scanf("%d%d", &a, &b) != EOF) { if (a == b && b == -1) { break; } if (a == b && b == 0) { int size = v.size(); //之前没有判断没有节点时的情况所有一直WA if (size == 0) { cout << "Yes" << endl; continue; } int i; int flag = 1; for (i = 0; i < size; i++) { int a_father = find_father(v[i].u); int b_father = find_father(v[i].v); if (a_father == b_father) { flag = 0; break; } else { union_set(a_father, b_father); } } if (flag) { s.clear(); for (i = 0; i < size; i++) { if (father[v[i].u] == 0) { s.insert(v[i].u); } if (father[v[i].v] == 0) { s.insert(v[i].v); } } if (s.size() == 1) { cout << "Yes" << endl; } else { cout << "No" << endl; } } else { cout << "No" << endl; } s.clear(); v.clear(); memset(father, 0, sizeof(father)); } else { if (a != b) { edge temp; temp.u = a; temp.v = b; v.push_back(temp); } } } return 0; }