题意
思路
-
这题明显的是带权并查集,但是我们要多维护一个集合大小 num [] 数组,因为我们这题的带权并查集维护的不仅是节点之间的相互关系,而需要维护的是实际真实的距离。有 num 之后就方便我们维护实际距离了。
-
带权并查集核心
-
维护真实边权的核心:
代码
/* #include <iostream> */
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 30005;
int f[N], d[N], num[N];
int find(int x)
{
if (f[x] != x)
{
int root = find(f[x]);
d[x] += d[f[x]];
f[x] = root;
}
return f[x];
}
int main()
{
for (int i = 1; i < N; i ++) f[i] = i, num[i] = 1, d[i] = 0;
int m; scanf("%d ", &m);
char ch; int x, y;
while (m --)
{
scanf("%c %d %d ", &ch, &x, &y);
int fx = find(x), fy = find(y);
if (ch == 'M')
{
f[fx] = fy;
d[fx] = num[fy];
num[fy] += num[fx];
}
else
{
int dis = -1;
if (fx == fy)
dis = max(abs(d[x] - d[y]) - 1, 0);
printf("%d\n", dis);
}
}
return 0;
}