并查集模板

本文最后更新于:5 小时前

并查集理论就不过多的阐述了,这个数据结构及其解决的等价类相关的问题应该算是比较简单了。

tips

并查集通常使用数组static  int[]  p=new  int[LEN]static \ \ int[] \ \ p = new \ \ int[LEN]存储某一节点所属等价类的父节点。即p[i]==j,1<=j<=np[i] == j, 1<=j<=n时,表示节点ii的父节点是节点jj

对于某一根节点rrp[r]p[r]的值可以有多种形式。

  • 可以规定p[r] =  rp[r] \ = \ \ r的节点为根节点,但这样的规则使根节点并未携带其他任何信息。
  • 若我们规定p[r]0p[r] \leq 0表示根节点,那么可以用\abs{p[r]}表示一定的信息。比如该根节点表示的等价类的元素数量。

find

这里的find方法包含了路径压缩。当节点xx是根节点,或是根节点的直接子结点时,不需要路径压缩,直接返回即可。

  • y总说实现了路径压缩就可以近似认为并查集相关方法复杂度为O(1)

  • 根节点的直接子结点,不要忘记这一类判断,不然会出错…

1
2
3
4
5
6
7
static int find(int x) {
if(p[x] == 0) return x;
if(p[p[x]] == 0) return p[x];

p[x] = find(p[x]);
return r;
}

union

只有当两节点不在同一个等价类中才可以合并。

所以y总没有加if,出错了…

1
2
3
4
5
6
7
static void union(int u, int v) {
int a = find(u);
int b = find(v);
if(a != b) {
p[a] = b;
}
}

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!