給定若干條邊 (x, y),構成無向圖。每組數據以 0 0 結束,全部數據以 -1 -1 結束。判斷每組邊是否構成一棵樹(即連通且無環)。輸出 "Yes" 或 "No"。
並查集維護連通分量。處理每條邊 (x, y):
find(x) == find(y)),則成環 → 標記非樹。最後檢查:若無環且只有一個連通分量(即所有出現過的節點屬於同一根),則是樹。
#include <cstdio>
const int MAXN = 100005;
int parent[MAXN];
bool visited[MAXN];
int findRoot(int x) {
while (x != parent[x]) x = parent[x];
return x;
}
void init() {
for (int i = 1; i < MAXN; i++) {
parent[i] = i;
visited[i] = false;
}
}
int main() {
int x, y;
bool isTree = true;
int components = 0;
init();
while (scanf("%d%d", &x, &y) == 2) {
if (x == -1 && y == -1) break;
if (x == 0 && y == 0) {
// 判斷當前圖
if (!isTree) puts("No");
else {
int roots = 0;
for (int i = 1; i < MAXN; i++)
if (visited[i] && parent[i] == i) roots++;
puts(roots == 1 ? "Yes" : "No");
}
// 重置
isTree = true;
init();
} else {
visited[x] = visited[y] = true;
int rx = findRoot(x), ry = findRoot(y);
if (rx == ry) isTree = false;
else parent[ry] = rx;
}
}
return 0;
}
並查集是判斷無向圖是否為樹的經典工具:檢測環(合併前同根)+ 檢測連通性(最終根數量為 1)。本題輸入格式特殊,注意 0 0 分隔測試案例,-1 -1 結束整個輸入。