本题也是个标准的并查集题解。
操作完并查集之后,就是要找和0节点在同一个集合的元素有多少。
注意这个操作,须要先找到0的父母节点。然后查找有多少个节点的额父母节点和0的父母节点同样。
这个时候须要对每一个节点使用find parent操作。由于最后状态的时候,节点的parent不一定是本集合的根节点。
#include <stdio.h> const int MAX_N = 30001; struct SubSet { int p, rank; }sub[MAX_N]; int N, M; void initSub() { for (int i = 0; i < N; i++) { sub[i].p = i; sub[i].rank = 0; } } int find(int x) { if (x != sub[x].p) sub[x].p = find(sub[x].p); return sub[x].p; } void unionTwo(int x, int y) { int xroot = find(x); int yroot = find(y); if (sub[xroot].rank < sub[yroot].rank) sub[xroot].p = yroot; else { if (sub[xroot].rank == sub[yroot].rank) sub[xroot].rank++; sub[yroot].p = xroot; } } int main() { int a, b, k; while (scanf("%d %d", &N, &M) && (N || M)) { initSub(); for (int i = 0; i < M; i++) { scanf("%d", &k); if (k > 0) scanf("%d", &a); for (int j = 1; j < k; j++) { scanf("%d", &b); unionTwo(a, b); } } int sus = 1, p = find(0); for (int i = 1; i < N; i++) { if (find(i) == p) sus++; } printf("%d ", sus); } return 0; }