参考博客
带权并查集就是一系列能够维护结点到根节点权值的特殊并查集。
常用于区间可合并的求和和判断。甚至差值也可以判断。十分巧妙。
在查询操作上,维护权值,路径压缩到根节点的过程,将中间的路径长度也加到该点上。
int find(int x)
{
if (x != f[x])
{
int t = f[x];
f[x] = find(f[x]);
sum[x] += sum[t];
}
return f[x];
}
由于我们处理的是到根节点的距离,真正能计算的是同一集合的,如果不在同一集合中无法计算。
我们如何合并两个关系呢?
这里盗用了图
但是这个图比较经典。
显然以
x
x
x到
p
y
py
py距离不变来做等式即可求解。
bool uni(int x,int y,ll s){
int px=find(x);
int py=find(y);
if(px!=py){
f[py]=px;
sum[py]=s+sum[x]-sum[y];
return true;
}
else{
return (sum[y]-sum[x])==s;
}
}
这就是带权并查集的基本操作了。