题目链接:The Suspects

很简单的一道并查集,关键在如果保存每个集合的元素个数和如何合并处理。

值得学习的一点:把当前集合的元素个数存在根节点上,每次合并的时候,对根节点进行操作即可。

应用归类:集合合并,判断两点是不是在同一个集合,查找某一个集合上的元素个数等。

 

代码
#include<stdio.h>
#define NN 30005
int n;
int bin[NN];
int cnt[NN]; // 保存当前根节点所在集合的元素个数
int find(int x){
int r = x;
while (bin[r] != r){
r
= bin[r];
}
int y = x;
while (bin[y] != y){
/* 很早以前都是用三句话实现压缩,今天终于找到两句话搞定的方法了*/
y
= bin[y];
bin[y]
= r;
}
return r;
}
void merge(int x, int y){
int fx, fy;
fx
= find(x);
fy
= find(y);

if (fx != fy){
/*每次合并的时候,都将根节点指向0*/
if (fx == 0){
bin[fy]
= fx;
cnt[fx]
+= cnt[fy];
}
else if (fy == 0){
bin[fx]
= fy;
cnt[fy]
+= cnt[fx];
}
else{
bin[fx]
= fy;
cnt[fy]
+= cnt[fx];
}
}
}
int main()
{
int n, m, i, num, cur, next;
while (scanf("%d%d", &n, &m) != EOF){
if (n == 0 && m == 0) break;
for (i = 0; i < n; i++){
bin[i]
= i;
cnt[i]
= 1;
}

while (m--){
scanf(
"%d%d", &num, &cur);
while (--num){
scanf(
"%d", &next);
merge(cur, next);
cur
= next;
}
}
printf(
"%d\n", cnt[0]);
}
return 0;
}

 

posted on 2010-07-14 11:16  ylfdrib  阅读(375)  评论(0编辑  收藏  举报