NOI2002 银河英雄传说 带权并查集

题目链接

http://noi-test.zzstep.com/contest/0x40%E3%80%8C%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E8%BF%9B%E9%98%B6%E3%80%8D%E4%BE%8B%E9%A2%98/4101%20%E9%93%B6%E6%B2%B3%E8%8B%B1%E9%9B%84%E4%BC%A0%E8%AF%B4

分析

维护并查集中每个节点的父亲的同时,维护每个节点到父亲的距离,以及每个集合的元素个数。

AC代码

#include 
#include 
#include 

using namespace std;

inline int read() {
	int num = 0;
	char c = getchar();
	while (c < '0' || c > '9') c = getchar();
	while (c >= '0' && c <= '9')
		num = num * 10 + c - '0', c = getchar();
	return num;
}

const int maxn = 3e4 + 5, maxi = 3e4;

int f[maxn], d[maxn], size[maxn];

int find(int x) {
	if (x == f[x]) return x;
	int root = find(f[x]);
	d[x] += d[f[x]];
	return f[x] = root;
}

inline void merge(int a, int b) {
	a = find(a), b = find(b);
	d[a] = size[b], size[b] += size[a], f[a] = b;
}

int main() {
	int t = read();
	for (int i = 1; i <= maxi; ++i) f[i] = i, size[i] = 1;
	while (t--) {
		char op[2];
		scanf("%s", op);
		int a = read(), b = read();
		if (op[0] == 'M') merge(a, b);
		else if (op[0] == 'C') {
			if (find(a) == find(b)) printf("%d\n", abs(d[a] - d[b]) - 1);
			else printf("-1\n");
		}
	}
	return 0;
}

你可能感兴趣的:(数据结构,《算法竞赛进阶指南》)