特殊并查集

普通的并查集只能实现简单的合并 (Unite)和查询(Find),而无法高效的实现转移(move)和删除(erase)。为了解决该问题,我们可以使用带虚节点的特殊并查集,在实现高效合并和查询的同时,用空间换时间,实现高效的转移和删除操作。
以下为代码实现(main函数略):

#include <iostream>
#include <vector>
using namespace std;
vector<int> pa, Size, sum;

void Init(int n) {
	pa.resize(2 * n + 10);
	Size.resize(2 * n + 10,1);
	sum.resize(2 * n + 10);

	for (int i = 1;i <= n;i++) {
		pa[i] = n + 
		sum[n + i] = i;
	}
	for (int i = n + 1;i <= 2 * n;i++) {
		pa[i] = i;
	}
}

int Find(int x) {
	if (pa[x] != x)pa[x] = Find(pa[x]);
	return pa[x];
}

void unite(int x, int y) {
	x = Find(x), y = Find(y);
	if (x == y)return;

	pa[x] = y;
	Size[y]+=Size[x];
	sum[y] += sum[x];
}

void move(int x,int y){
	int fx = Find(x), fy = Find(y);
	if (fx == fy)return;

	pa[x] = fy;
	Size[fy]++;
	Size[fx]--;
	sum[fy] += x;
	sum[fx] -= x;
}
void erase(size_t x) {
 size_t y = find(x); 
 size[y]--; 
 pa[x] = id++; 
 }

在该代码实现中,使用虚节点代替真节点承担根的位置,使得真节点都存于叶子节点,从而使树最多为两层,省略了按秩合并,在删除和转移的操作中,只需更改虚节点,不会影响其他真节点。在理解和操作上也更直观,易理解,也可在此代码的基础上进行其他扩展操作,如维护树的边权,分离集合(虽然我还不会。。。)

posted @ 2026-04-17 14:23  十七code  阅读(4)  评论(0)    收藏  举报