PKU并查集,秩的运用

http://poj.org/status?result=0&user_id=297752873

#include<stdio.h>//
#include<stdlib.h>
int bin[30010],rank[30010];//
int findx(int x)
{
    if(bin[x]!=x)
     bin[x]=findx(bin[x]);//回溯是的压缩路径 
    return bin[x];
}
void merge(int x,int y)//这个函数里重要的是启发式合并,rank称为秩,这里是感染总数,但其实也是深度 
{
     int fx,fy;
     fx=findx(x);
     fy=findx(y);
     if(fx==fy)
     return ;
     if(rank[fx]>rank[fy])//这里的判断是要将深度小的作为最终节点 
     {
        bin[fy]=fx;//把大的接到小的那里 
        rank[fx]+=rank[fy];//然后把二者存储的感染总数相加,得合并的结果  
     }
     else{                //
           bin[fx]=fy;
           rank[fy]+=rank[fx];
          }
}
int main()
{
    int i,n,m,max,t,x;
    while(scanf("%d%d",&n,&m),n||m)
    {
        for(i=0;i<n;i++)
          bin[i]=i,rank[i]=1;//bin保存根结点,rank保存每个节点下的感染总数,其实也就是深度 
        while(m--)
          {
           scanf("%d",&t);
           for(i=0;i<t;i++)
           {
               scanf("%d",&x);
               if(i==0)
                 max=x;//如果是第一个,那就保存,留着跟之后的合并 
               else merge(max,x);//两个集合进行合并 
           }
          }
          x=findx(0);//找寻0的根结点 
          printf("%d\n",rank[x]);//输出根结点存储的感染总数 
    }
    return 0;   
}
View Code

 

posted @ 2013-07-23 14:06  执着追求的IT小小鸟  阅读(262)  评论(0编辑  收藏  举报