本題也是個標准的並查集題解。
操作完並查集之後,就是要找和0節點在同一個集合的元素有多少。
注意這個操作,需要先找到0的父母節點,然後查找有多少個節點的額父母節點和0的父母節點相同。
這個時候需要對每個節點使用find parent操作,因為最後狀態的時候,節點的parent不一定是本集合的根節點。
#includeconst 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\n", sus); } return 0; }