哈哈,第一个并查集终于写出来了,虽然从昨天看到现在,不现在才完全搞清楚过程并第一次用代码实现,好兴奋
#include<stdio.h>
typedef struct //定义树节点 ,本题中,集合的名字用代表人的数字 ,node[3]代表代号为三人的人所在的树节点
{
int father;
int size;
}xx;
xx node[30002];
int find(int x) //函数,用来返回节点x所在树的树根
{
while(x!=node[x].father) //如果 节点x的父节点不等于x,那么把x的父节点赋给x,继续找
x=node[x].father;
return x;
}
void Union(int x,int y) //函数,合并两个集合,两棵树
{
int a=find(x),b=find(y);
node[x].father=a; //此步骤会让树变成只有根和叶的形式,即只有两层
node[y].father=b;
if(a<b){
node[a].size+=node[b].size; //和并到根小的树上(集合上)
node[b].father=a;
}
if(a>b){
node[b].size+=node[a].size;
node[a].father=b;
}
}
int main()
{
int m,n,k,i,j,x,y;
while(scanf("%d%d",&n,&m)&&(n!=0||m!=0)){
for(i=0;i<n;i++){
node[i].father=i; //把每个节点的根初始化为自己,大小初始化为1
node[i].size=1; //初始化后,每个节点都是一棵树 ,通过后面的操作不断地把树合并
}
for(i=0;i<m;i++){ //依次把每一组的人合并成一个集合
scanf("%d",&k);
scanf("%d",&x); //期间,如果一个元素再次出现,会把同时包含 这个元素的两个集合合并,依次进行
for(j=1;j<k;j++){
scanf("%d",&y);
Union(x,y);
}
}
printf("%d\n",node[0].size);
}
return 0;
}