NSYSU 有 n 個學生(0~n-1),m 個學生組。規則:若一組中有嫌疑人,全組都是嫌疑人。初始 0 號為嫌疑人。給定組員名單,求最終嫌疑人數。
輸入多組測試,n ≤ 30000, m ≤ 500。每組第一行 k 及 k 個學生號。n=m=0 結束。
學生之間的「同組」關係具有傳遞性,天然形成不相交集合。0 號所在集合的大小即為答案。
#include <cstdio>
#include <cstring>
const int MAXN = 30010;
int parent[MAXN], sz[MAXN];
int find(int x) {
return parent[x] == x ? x : parent[x] = find(parent[x]);
}
void unite(int a, int b) {
a = find(a); b = find(b);
if (a == b) return;
if (sz[a] < sz[b]) swap(a, b);
parent[b] = a;
sz[a] += sz[b];
}
int main() {
int n, m;
while (scanf("%d%d", &n, &m) == 2 && (n || m)) {
for (int i = 0; i < n; ++i) { parent[i] = i; sz[i] = 1; }
for (int i = 0; i < m; ++i) {
int k, first; scanf("%d%d", &k, &first);
for (int j = 1; j < k; ++j) {
int x; scanf("%d", &x);
unite(first, x);
}
}
printf("%d\n", sz[find(0)]);
}
return 0;
}
這道題是並查集入門級應用,清晰展示了「等價關係合併 + 根節點信息維護」的模式。