【算法简述】基础数据结构-带权并查集

带权并查集

  • 带权并查集实现
  • 带权并查集合并

一般并查集只维护每个节点的根节点,但是带权并查集还可以维护每个节点到其更节点的距离,因此,这里带权并查集有重要的作用。(一开始看发现完全看不懂,但是看了 资料 懂了那么一点点…)


带权并查集实现

现在给你们讲讲这个带权的并查集该怎么弄,一般就是这样的解题思路:

  • 将其中两个队列合并,也就是把第一个队列存到第二个队列后面,以后好方便查询这个合并的值。
  • 查询某个元素在哪一位,排在第几位,方便以后继续执行。

很显然,举个例子,这是一般的路径压缩:

int get(int x){
	if(fa[x]==x){
		return x;
	}
	return fa[x]=get(fa[x]);
}

这样,他会直接执行和更新语句,就是点的权值。
那么,就用带权并查集解决这类问题,基本的带权值在途中可能是对应关系,用ad[i]表示节点i到父节点的距离,从i到他所在树的根的ad直接累计起来,算出的结果就是从i到队首的距离,因为这里根节点就是队首。开始的时候,一个点一列,ad[i]=0,未初始化。
【算法简述】基础数据结构-带权并查集_第1张图片

  1. 如上图,如果此图是带权的并查集,最后根节点的距离就是3到5的距离。
  2. 相当于x的距离点到距离等于x到ad[x]的距离加上ad[x]的距离。
int get(int x){
	if(fa[x]==x){
		return x;
	}
	int y=fa[x];
	fa[x]=get(y);
	dist[x]+=dist[y];
	return fa[x];
}

我们先将原记录点的编号给记录下来,然后继续查询,权值加上父节点的权值,然后,我们下一步进行分支。

带权并查集合并

将才加上了并查集,这次,我来解决并查集的合并,把第一个队列搬到第二个队列里面,把第一个队列的集合合并到第二个队列的集合,通过get带入两个集合内,我们都会加上队列的长度,首先就是:

void merge(int x,int y,int v){
    int a=get(x),b=get(y);
    if(a==b)return;
    fa[a]=b;
    dist[a]=-dist[x]+dist[y]+v;
}

【算法简述】基础数据结构-带权并查集_第2张图片
对于这些元素,这是z的节点。
实在搞不懂,可以尝试背代码。
通过小小的改动,我们就可以查到这元素中的信息,带权并查集维护每一个点的权值而这个权值用来记录节点中的一些关系,你会发现get写法很固定,但merge的写法要根据不同的定值。

你可能感兴趣的:(【算法简述】基础数据结构-带权并查集)