洛谷 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;
}
posted @ 2019-03-04 23:04  新新人類  阅读(180)  评论(0编辑  收藏  举报