多开两个数组保存结点到根的距离和所在集合大小,中间战舰数量是x到根的距离减y到根的距离减一。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn = 3e4 + 5;
int f[maxn], num[maxn], rd[maxn];
//num保存当前集合大小,rd保存结点到根的距离
int T;
int find(int x) {
if (f[x] == x)
return x;
int k = f[x];
f[x] = find(f[x]);//路径压缩
rd[x] += rd[k];//更新当前节点到根的距离
return f[x];
}
int main() {
for (int i = 1; i < maxn; i++)
f[i] = i, num[i] = 1;
scanf("%d", &T);
char t[5];
int x, y;
while (T--) {
scanf("%s%d%d", t, &x, &y);
int fx = find(x), fy = find(y);
if (t[0] == 'M') {
f[fx] = fy;
rd[fx] += num[fy];//更新x的根到y的根的距离
num[fy] += num[fx];//更新y所在集合大小
num[fx] = 0;//x所在集合并到y集合后面,集合大小归零
}
else {
if (fx != fy) {
printf("-1\n");
continue;
}
printf("%d\n", abs(rd[x] - rd[y]) - 1);
}
}
system("pause");
return 0;
}