题目链接: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;
}