并查集的简单实现

并查集的特点:

1.可以高效查询元素 a 和元素b是否属于同一组 

2.合并元素a和元素b所在的组 (无法分割)

初始化:n个节点来表示元素,最开始没有边。

合并:从一个组的跟向另一个组连边,这样两棵树就变成了一棵树,也就把两个组合并为一个组了。

查询:为了查询两个节点是否属于同一个组,我们需要沿着树往上走,来查询包含这个元素的根上谁,如果是同一个根,则属于同一个组。

避免退化:对于每棵树,记录这棵树的高度(rank),合并时如果两棵树的rank不同,那么从rank小的向rank大的连边。

路径压缩:对于每一个节点,一旦向上走到了一次根节点,就把这个点到父亲的边改为直接连上根。

模板实现:

 1 int par[maxn]; //父亲
 2 int rank[maxn]; //树的高度
 3 //初始化n个元素
 4 void init(int n) {
 5     for(int i=0; i<n;i++) {
 6         par[i]=i;
 7         rank[i]=0;
 8     }
 9 }
10 //查询树的根 
11 int find(int x) {
12     if(par[x]==x) {
13         return x;
14     }
15     else return par[x]=find(par[x]);
16 }
17 //合并x和y所属集合
18 void unite(int x,int y) {
19     x=find(x);
20     y=find(y);
21     if(x==y) return;
22     
23     if(rank[x] < rank[y]) {
24         par[x]=y;
25     } else {
26       par[y]=x;
27       if(rank[x]==rank[y]) rank[x]++;
28     }
29 }
30 //判断x 和y是否属于同一个 集合
31 bool same(int x,int y) {
32     return find(x) == find(y);
33 }
原文地址:https://www.cnblogs.com/nowandforever/p/4481331.html