238. 银河英雄传说
带权并查集:维护结点到其根结点的的一些信息的并查集
本题维护的是每一个结点到它的根的距离
#include<iostream>
using namespace std;
const int N = 30010;
int p[N];
int d[N];
int cnt[N];
/*
d[x]本身存放的是x到它的父节点的距离,
在经过一遍find之后需要将d[x]更新成x到它的根节点的距离
*/
int find(int x){
if(p[x] != x){
int root = find(p[x]);
d[x] += d[p[x]];
p[x] = root;
}
return p[x];
}
void merge(int x, int y){
x = find(x), y = find(y);
p[x] = y, d[x] = cnt[y];
cnt[y] += cnt[x];
}
int main(){
int T;
cin >> T;
for(int i = 1; i <= N; i ++) p[i] = i, cnt[i] = 1;
while(T --){
char op;
int i, j;
cin >> op >> i >> j;
if(op == 'M') merge(i, j);
else{
int x = find(i), y = find(j);
if(x != y) puts("-1");
else cout << abs(d[i] - d[j]) - 1 << endl;
}
}
return 0;
}