什么是并查集?
并查集就是某件事件内,因某种条件的约束进行分类,在满足条件的情况下,分成几类,每类里面有多个元素,这些元素就是该类的孩子,此类就类似根,其逻辑形式表示为有多颗多叉树,组成的森林,其根表示不同类的情况.
并查集思想:
1.首先根据问题规模进行初始化,假设有规模为n的问题,设数组为fa[],fa[i] = i (1 <= i <= n),其表明每个初始状态为其本身,有n个节点的森林
2.找到其所在的类的集合,即找到问题a的根节点处,当前节点距离根节点可能有多个节点处
可用使用递归或者迭代的方式求出即
int get(int x)
{
if(x == fa[x]) return x;
return fa[x] = get(fa[x]);
//假设该节点到根节点处经过有多个节点,压缩路径,表明一步到根,只需一次操作即可
}
3.合并俩个不同的类的集合,合并为一个类,即先找到俩所属类的根下标,令该下标等于另外一个类的根下标即可完成合并操作。代码如下:
void merge(int x,int y)
{
x = get(x), y = get(y); //找到 x,y的根
if(x == y) return ; //根相同不做操作
fa[x] = y; //当前根下标下的赋上y,合并成功
}
边带权的并查集
什么是边带权的并查集呢?即该节点与其父节点之间的值,类似无向有权图,通常在get操作中进行更新.
int get(int x)
{
if(x == fa[x]) return x;
int root = get(fa[x]);
//修改当前节点与根结点处的权值
如 d[x] += d[fa[x]];
return fa[x] = root;
}
扩展域思想
即根据题目要求,建立多个并查集,分别表示不同的关系,根据互相之间的关系来判定合并到合适并查集中.