您的位置:首页 > 其它

并查集的带权问题(判断区间和)

2018-02-08 23:48 134 查看
并查集是很不错,但它是不是只支持无权的连边呢?
答案是:不存在的.
并查集是可以支持带权的,而且还能路径压缩.
那么不路径压缩还可以求路径长度,路径压缩了还能怎么求?
因为路径压缩后,我们的路径长度并不是每个都储存的,而基本只存到最老的祖先的距离.
你不知道前缀和吗?用前缀和啊.
若前缀和不行,取消路径压缩就行了.
一般前缀和还是可以的.
例如下面这道题:
给出n个信息,每个信息包括ai,bi,ci,表示区间[ai,bi]的和为ci,试判断有几条信息是错误的,注意,只有整数点上有值.
于是我们根据上面的理论,很容易得出以下代码:
class forest{
int father[maxn],n,dis[maxn],sum; //这是要多维护一个与父亲的距离
void clear(int x) const{
n=x;sum=0;
for (int i=1;i<=n;i++)
father[i]=i,dis[i]=0; //一开始每个点与祖先的距离都为0
}
int root(int u) const{
if (u==father[u]) return {u,0};
else {
int fa=father[u]; //记录下u原来的父亲
father[u]=root(father[u]); //将u的父亲更新
dis[u]+=dis[fa]; //进行路径长度的更新
father[u]=d; //更新u的父亲为祖先节点
return d; //返回祖先节点
}
}
void merge (int x,int y,int num) const{
if (x>y) swap(x,y); //若x大于y,说明dis[y]-dis[x]为负数,会出问题,所以要交换
int rx=root(x),ry=root(y); //得出x的祖先以及y的祖先
if (rx==ry){
if (dis[y]-dis[x]!=num) sum++; //若输进来的答案与已处理出的答案有差距,则错误的信息数量加1
return;
}
fa[rx]=ry; //使x的祖先的父亲改为y的祖先
root(x); //使x总是直接连接祖先
}
};这就是带权的并查集的用处与写法.
当然,有些时候还是不要路径压缩比较好,不然容易出问题.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: