并查集的题目
// 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;
}

京公网安备 11010502036488号