带权并查集稍微注意下细节

#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
 posted on 2024-09-29 10:41  ruoye123456  阅读(22)  评论(0)    收藏  举报