带权并查集稍微注意下细节、
#include<bits/stdc++.h>
using namespace std;
#define x first
#define y second
typedef pair<int,int> PII;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef vector<string> VS;
typedef vector<int> VI;
typedef vector<vector<int>> VVI;
vector<int> vx;
inline int mp(int x) {return upper_bound(vx.begin(),vx.end(),x)-vx.begin();}
inline int log_2(int x) {return 31-__builtin_clz(x);}
inline int popcount(int x) {return __builtin_popcount(x);}
inline int lowbit(int x) {return x&-x;}
const int N = 30010;
//d[i]表示i到根节点的距离
int f[N],d[N],sz[N];
int find(int u)
{
if(f[u] == u) return u;
int t = find(f[u]);
//d表示到根节点的距离不能反复合并,因为f[u]可能被更新为根节点
//if(!d[u]||f[u]!=t) d[u] = d[f[u]] + 1;
d[u] += d[f[u]];
sz[t] += sz[u], sz[u] = 0;
return f[u] = t;
}
void merge(int u,int v)
{
int f1 = find(u), f2 = find(v);
if(f1 != f2) f[f1] = f2, d[f1] = sz[f2], sz[f2] += sz[f1], sz[f1] = 0;
}
void solve()
{
for(int i=1;i<N;++i) f[i] = i, d[i] = 0, sz[i] = 1;
int q;
cin>>q;
for(int i=0;i<q;++i)
{
char op;
cin>>op;
int u,v;
cin>>u>>v;
if(op == 'M') merge(u,v);
else
{
//需要特判一下u是否等于v
if(u == v) cout<<"0\n";
else if(find(u)==find(v))
{
cout<<abs(d[u] - d[v]) - 1<<'\n';
}
else cout<<"-1\n";
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T = 1;
//cin>>T;
while(T--)
{
solve();
}
}
// 5
// 4
// 3
// 2
// 1
标签:sz,typedef,return,f1,int,查集,f2,带权,NOI2002
From: https://www.cnblogs.com/ruoye123456/p/18439096