1、并查集概念
当我们需要判断一个集合中的两个元素x,y是否同属于一个集合时,我们可以使用并查集的方法进行查询。其核心思路在于将一个数组转化成一棵树的形式:每个节点初始时都认为是一棵独立的树,当两个节点同属于一个集合时,我们可以将其中一个节点指向另一个节点用于表示两个节点同属于一个集合。因此当我们想要确定两个节点是否同属于一个子集时,我们只需要比较他们二者的根节点是否相同即可。因此并查集中的基础操作有两个:find判断两个节点是否相同;union合并两个相同的节点。
2、并查集实现
1、Find()
实现find函数时,由于我们初始化时将各个节点的父节点parent[x]定义为自己本身,因此在查询时若parent[x]等于自己说明自己就是根节点,可以直接返回;若不相等说明自己的parent[x]记录的是其父节点的值,将其传入find继续查找。
int find(int x)
{
return parent[x] == x ? x : find(parent[x]);
}
2、Union()
当两个元素同属于一个子集时,我们需要将两个独立的树进行合并,此时我们可以将其中一棵树的根节点指向另一棵树的根节点实现合并。
void to_union(int x1, int x2)
{
int p1 = find(x1);
int p2 = find(x2);
parent[p1] = p2;
}
3、完整代码
#include <vector>
class DisjSet
{