zoj 1789The Suspects 并查集

  哈哈,第一个并查集终于写出来了,虽然从昨天看到现在,不现在才完全搞清楚过程并第一次用代码实现,好兴奋大笑大笑大笑
#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;
  }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值