洛谷 p1196 带权并查集
带权并查集是记录该父亲有多少子孙 在合并时优先将子孙少的合并到子孙多的上面
这题需要多加一个当前列的个数 用来更新两战舰中间的差值
//ios::sync_with_stdio(false);
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN = 30010;
int fa[MAXN];
int rak[MAXN]; //i战舰前有多少战舰
int num[MAXN]; //当前列有多少战舰
int find(int k)
{
if(fa[k]==k) return k;
int fn=find(fa[k]);
rak[k]+=rak[fa[k]];
num[k]=num[fa[k]];
fa[k] = fn;
return fn;
}
void unon(int a,int b)
{
int r1 = find(a),r2 = find(b);
if(r1!=r2)
{
fa[r1] = r2;
rak[r1] = rak[r2]+num[r2];
num[r2] +=num[r1];
num[r1] = num[r2];
}
}
int main()
{
for(int i=0;i<MAXN;++i)
{
fa[i] = i;
num[i] = 1;
}
int T;
cin >> T;
char op;
int l,r;
for(int i=0;i<T;++i)
{
cin >>op >> l >> r;
if(op=='M')
{
unon(l,r);
}
if(op=='C')
{
if(find(l)==find(r)) cout << abs(rak[r]-rak[l]) -1<< endl;
else cout << -1 <<endl;
}
}
return 0;
}