并查集的题目
// runtime: 4ms // space: 608K #include <iostream> using namespace std; const int MAX = 10000; int father[MAX]; int height[MAX]; int inDegree[MAX]; bool visited[MAX]; void Initial () { // 初始化 for (int i = 0; i < MAX; ++i) { father[i] = i; height[i] = 0; visited[i] = false; inDegree[i] = 0; } } bool IsTree() { // 判断是否符合树的定义 int part = 0, root = 0, isTree = true; for (int i = 0; i < MAX; ++i) { if (!visited[i]) continue; if (inDegree[i] == 0) root++; if (father[i] == i) part++; if (inDegree[i] > 1) return false; // 如果某个节点的入度大于1,直接返回false } if (root != 1 || part != 1) { // 一棵树应该只有一个节点的入度等于0 isTree = false; } if (root == 0 && part == 0) { // 空树也是树... isTree = true; } return isTree; } int Find(int x) { // 查找根结点 if (x != father[x]) { father[x] = Find(father[x]); // 路径压缩 } return father[x]; } void Union(int x, int y) { // 合并集合 x = Find(x); y = Find(y); if (x != y) { if (height[x] < height[y]) { father[x] = y; } else if (height[x] > height[y]) { father[y] = x; } else { father[x] = y; height[y]++; } } } int main() { int a, b, k = 1; Initial(); while (cin >> a >> b) { if (a == -1 && b == -1) break; else if (a == 0 && b == 0) { if (IsTree()) { cout << "Case " << k++ <<" is a tree." << endl; } else { cout << "Case " << k++ <<" is not a tree." << endl; } Initial(); // 这里别忘记 } else { Union(a, b); visited[a] = true; visited[b] = true; inDegree[b]++; } } return 0; }