d[x] 来表示x到祖宗节点的距离
l[x] 表示每一个集合最后的点
对于M指令, 把a的祖宗节点的父亲设为 b所在列的最后一个,p[find(a)] = l[find(b)];
路径压缩时维护d[]数组
当x点是第一次被查询时,即d[x] == 0,并且x不是根节点,d[x]=d[p[x]] + 1,因为第一次查询p[x]未被更新过
否则,d[x]就是x到p[x]的距离加上p[x]到p[p[x]]的距离,d[x] = d[x] + d[p[x]]
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 30010;
int p[N], d[N], l[N];
void init()
{
for (int i = 1; i < N; i ++ ) p[i] = i, l[i] = i;
}
int find(int x)
{
if (p[x] != x) {
int root = find(p[x]);
if (d[x]) d[x] += d[p[x]];
else d[x] = d[p[x]] + 1;
p[x] = root;
}
return p[x];
}
void merge(int a,int b)
{
int pa = find(a);
int pb = find(b);
if (pa != pb) {
p[pa] = l[pb];
l[pb] = l[pa];
}
}
int query(int a,int b)
{
int pa = find(a);
int pb = find(b);
if (pa != pb) return -1;
else return abs(d[a] - d[b]) - 1;
}
int main()
{
int n;
cin >> n ;
init();
for (int i = 1; i <= n; i ++ ) {
int a, b;
char op;
cin >> op >> a >> b;
if (op == 'M') merge(a, b);
else cout << query(a, b) << endl;
}
}