北大培训第4天 并查集 和 最强联通分支 桥 割点
在pku中的讲解中对于并查集最重要的一点是: 如果进行find函数寻找父亲节点(采用路径压缩的方式)的话就不用rank来构建生成树了,产生的作用的结果是一样的。
在定义中,可以用数据的结构提变量来存储一些相关的信息。
这是对暑假训练并查集的相关的改进:
the suspect 利用的是在结构体里定义一个total的值,记录集合的数量(根节点tatal值表示集合的数量)
post code:
#include<stdio.h> struct Cnode{ int parent; int total; // 这里的total值是对算法的优化,可以直接得出结论。 } stu[50010]; int find(int i) //采用路径压缩的话就可以减少使用rank值来进行树的构成了,这样的时间复杂度不变 { if(stu[i].parent==i) return stu[i].parent; else { stu[i].parent=find(stu[i].parent); return stu[i].parent; } } void Union(int num1,int num2) { int p1,p2; p1=find(num1); p2=find(num2); if(p1==p2)return; else { stu[p1].parent=p2; stu[p2].total+=stu[p1].total; } } int main() { int i,m,n,j,max,num1,num2; while(scanf("%d %d",&m,&n)&&m!=0) { for(i=0;i<m;i++) { stu[i].parent=i; stu[i].total=1; } for(i=1;i<=n;i++) { scanf("%d",&max); if(max==1)scanf("%d",&num1); else { scanf("%d",&num1); for(j=2;j<=max;j++) { scanf("%d",&num2); Union(num1,num2); } } } printf("%d\n",stu[find(0)].total); //根节点的total值表示了这个集合里含有的元素的数量 } }