带权并查集——并查集3(以后改进写法,现在讲的不易懂)

在了解带权并查集前,我们先要理清楚我们前面讲的并查集的路径压缩。

int find(x){
	int p=x;
	if(p!=pre[p])pre[p]=find(pre[p]);
	return pre[p];
}

前面我们讲了,这一步操作能够使得find路径上的节点全部指向根节点。
对于一般的并查集来说,我们仅需要知道每个节点的父节点是谁,进而用find可以找到他的根节点。
对于带权并查集,我们要知道每个节点与他父亲之间的权值。(实际上这个权值是对关系的编码,用权重表示关系,具体后面结合题目来说) 进而用find可以找到他与根节点之间的权值(关系)。
我们知道pre[]数组是保存某个节点的父节点是谁。而加权并查集要一个value[]数组保存某个节点与他父节点之间的权值。而这个权值在其父节点改变时自然也会发生改变。
假设这里的权值表示距离,长度。
带权并查集路径压缩

int find(x){
	int p=x;
	if(p!=pre[p])
	{
		int t=pre[p];
		pre[p]=find(pre[p]);
		value[p]+=value[t];//随着权值表达的关系不同而变化。
	}
	return pre[p];
}

上面的代码是什么意思呢,因为有p->pre[p]->…->root,其中value[t]代表t到其父节点的距离。很明显路径压缩后value[t]代表的是t到根节点的距离,该值=t到父节点的距离+t父节点到根节点的距离,这是一个递归关系。假如value[t的父节点]已经更新为t的父节点到root的距离,则value[t]就可通过+value[t的父节点]得出。而上面这个函数就可发现在求value[t]时,value[t的父节点]已经更新。
带权并查集的合并

int px=find(x);
int py=find(y);
if(px!=py)
{
	parent[px]=py;
	value[px]=value[y]+s-value[x];//s为x到y距离,随着权值表达的关系不同而变化。
}

第二个公式是由于x通过不同道路到py距离相同。
s+value[y]=value[x]+value[px];
//s为x到y距离,value[y]经过find已经成为y到fy距离。value[x]表示x到fx距离,value[px]表示px到py距离。
//未完待续。
例题1:HDU-3038

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值