问题:
解决:
思路上比较简单,利用并查集
1.合并操作,直接将两个元素所在的树合并,并且将新的树里每个元素到根节点的距离更新
2.查询操作,有两种情况
a.两元素不在同一棵树里,说明距离无法计算,输出-1
b.两元素在同一棵树里,利用两元素到根节点的距离作差来计算,具体的话又分成两种情况,两元素相邻或者不相邻,加个特判就可以
具体细节看代码
注意:
这道题多少有点无奈
首先大数据读入,必须用 scanf 和 printf ,其次是测试数据,它的数据间隔有一些中间是两个空格的,读入这个字符最好用 %s ,要不就 空格+%c ,因为这个我WA了好几次
代码:
#include <bits/stdc++.h>
using namespace std;
#define N 30010
//cnt_size[i]表示i所在链上的元素个数
//res_dis[i]表示i到其跟节点的距离
int f[N], res_dis[N], cnt_size[N];
int find(int x){
if(f[x] != x){
int fx = find(f[x]);
//路径压缩
res_dis[x] += res_dis[f[x]]; //修改x到根节点的距离
f[x] = fx; //修改根节点
}
return f[x];
}
int main(void)
{
int t; scanf("%d", &t);
for(int i = 1; i < N; i++){
//独立元素size为1
cnt_size[i] = 1;
f[i] = i;
}
while(t--){
char c; int a, b;
scanf(" %c%d%d", &c,&a,&b);
int pa = find(a), pb = find(b);
if(c == 'M'){
//pa到根节点距离等于pb链中元素个数
res_dis[pa] = cnt_size[pb];
//更新pb链大小
cnt_size[pb] += cnt_size[pa];
f[pa] = pb; //根节点修改
}
else{
if(pa != pb) printf("-1\n");
else printf("%d\n", max(0, abs(res_dis[a] - res_dis[b]) - 1));
}
}
return 0;
}