题目链接:点击这里
维护当前战舰到排头的距离,最后的结果如下:
- 当 时,
- 当 时,0
把 合并到 的后面的示意图如下,可以看到合并操作需要维护 和 :
相应地,并查集的find操作需要维护 ,其示意图如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 30010;
int p[N], d[N], sz[N];
int find(int x)
{
if(x != p[x])
{
int root = find(p[x]);
d[x] += d[p[x]];
p[x] = root;
}
return p[x];
}
int main()
{
int m;
scanf("%d", &m);
for(int i = 1; i < N; ++i) // 初始化
{
p[i] = i;
sz[i] = 1;
d[i] = 0;
}
while(m--)
{
char op[2];
int a, b;
scanf("%s%d%d", op, &a, &b);
if(op[0] == 'M')
{
int pa = find(a), pb = find(b);
d[pa] = sz[pb];
sz[pb] += sz[pa];
p[pa] = pb;
}
else
{
int pa = find(a), pb = find(b);
if(pa != pb) puts("-1");
else printf("%d\n", max(0, abs(d[a]-d[b])-1));
}
}
return 0;
}