PKU并查集,秩的运用
http://poj.org/status?result=0&user_id=297752873
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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; }