按秩合并的带权并查集,常在寻找公共朋友,构造最小生成树(Kruskal)算法中。
#define N 101 struct UnionSet { //p,父节点;rank,秩 int p[N],rank[N],sz; void init_set(int n) { sz=n; //设置每个元素父节点为其本身 for(int i=0;i<sz;i++) { p[i]=i; rank[i]=0; } } //按秩合并两个元素 void link_set(int x,int y) { if(rank[x]>rank[y]) p[y]=x; else p[x]=y; if(rank[x]==rank[y]) rank[y]++; } //寻找父节点 int find_set(int x) { if(x!=p[x]) p[x]=find_set(p[x]); return p[x]; } void union_set(int x,int y) { link_set(find_set(x),find_set(y)); } void compression_set() { for(int i=0;i<sz;i++) find_set(i); } };
修改第14行开始的代码即link_set()函数如下,可以计算属于某类元素的个数。
void link_set(int x,int y) { if(rank[x]>rank[y]) p[y]=x,rank[x]+=rank[y]; else p[x]=y,rank[y]+=rank[x]; }