您的位置:首页 > 其它

zoj 1789The Suspects 并查集

2011-08-09 16:44 204 查看
哈哈,第一个并查集终于写出来了,虽然从昨天看到现在,不现在才完全搞清楚过程并第一次用代码实现,好兴奋





#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: