并查集
为了能够动态维护若干个不重叠的集合,并支持合并于查询,我们使用一个树形结构存储每个集合,树上的每个节点都是一个元素,根节点是集合的代表元素。
并查集的操作包括两个:
- get:查询元素属于哪一个集合(返回根节点)。
- merge:将两个元素(或集合)合并。
路径压缩 按秩合并
**路径压缩:**可以在每次get操作时,将访问过的每个节点全部指向根节点。
**按秩合并:**在合并时将“秩”较小的根节点作为“秩”较大的根节点的子节点(秩可以定义为集合大小或树的深度)。
int fa[SIZE];//定义一个fa数组保存父节点
void init()//初始化fa数组
{
for (int i = 1; i <= n; i++)
fa[i] = i;
}
int get(int x)
{
if (x == fa[x])//x为代表元素
return x;
return fa[x] = get(fa[x]);//递归 同时路径压缩 将fa[x]赋值为代表元素
}
void merge(int x, int y)
{
fa[get(x)] = get(y);//让x的根节点作为y根节点的子节点
}
“扩展域” 与 “边带权” 的并查集:
例题:
https://blog.csdn.net/xukeke12138/article/details/104732342
https://blog.csdn.net/xukeke12138/article/details/104824640