Acwing238 并查集+思维

题目链接:https://www.acwing.com/activity/content/problem/content/1583/1/

解题思路:
首先拿到这道题目,我直接就想到使用一个d数组去存当前的节点到根节点之间的距离,但是后来写着写着发现在进行合并的时候没有办法进行维护;
由于以前从来没有写过去修改find数组;所以一直没什么思路;正解是用一个d数组去存储此节点到父节点的距离,由于find数组可以将所有的节点直接连接到根节点,所以恰好在优化时间复杂度的时候一起将其距离根节点的距离一起维护。
代码:

#include <iostream>
#include <cstdio>

using namespace std;

const int maxn = 30005;

char str[5];
int x, y;
int p[maxn];
int s[maxn];
int d[maxn];

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

int main(void) {
//	freopen("in.txt", "r", stdin);
	int T, n = 30000;
	scanf("%d", &T);
	for(int i = 1; i <= n; i ++) p[i] = i, s[i] = 1, d[i] = 0;
	while(T --) {
		scanf("%s%d%d", str, &x, &y);
		if(str[0] == 'M') {
			//x 所在列 全部放到列 y后面;
			int px, py;
			px = find(x);
			py = find(y);
			p[px] = py;
			d[px] = s[py];
			s[py] += s[px];
		} else {
			int px = find(x), py = find(y);
			if(px != py) puts("-1");
			else printf("%d\n", max(0, abs(d[x] - d[y]) - 1));
		}
	}

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值