并查集
并查集是什么
并查集是一种树形的数据结构,顾名思义,它用于处理一些不交集的 合并 及 查询 问题。 它支持两种操作:
- 查找(Find):确定某个元素处于哪个子集;
- 合并(Union):将两个子集合并成一个集合。

简单来说就是用树的形式来维护集合,支持合并和查询。
基本原理
每个集合用一棵树来表示,树根编号就是集合编号,每个节点用p[x]储存其父节点。
几个重要的问题
- 如何判断是不是树根?
判断x是否==p[x]. - 如何求x的集合编号?
while(p[x]!=x) x=p[x]; - 如何合并集合
px是x的集合编号,py是y的集合编号,只要让p[px]=py;
优化
路径压缩:搜一次顺便将路上的点连接到root节点。
核心操作
find函数(找到根节点顺便路径压缩)。
int find(int x){
if(p[x]!=x) p[x]=find(p[x]);
return p[x];
}
并查集的变形
维护数量的并查集 acwing 837.连通块中点的数量
维护距离的并查集 POJ 1182 食物链(带权并查集)
带权并查集的 find 函数
int find(int x){
if(p[x] != x){
int t = p[x];
p[x] = find(p[x]);
d[x] += d[t];
}
return p[x];
}
先把 p[x] 暂存是因为路径压缩完之后 p[x] 就变成 root 了,而不是现在的父节点。
带权并查集 Union
根据题目变化而调整,以下是一个例子
p[py] = px;
d[py] = d[x] - d[y] + z;
附上 CSDN 看到的一篇关于带权并查集的还不错的讲解。
https://blog.csdn.net/yjr3426619/article/details/82315133

浙公网安备 33010602011771号