UVA 11987 Almost Union-Find(并查集)

本来觉得挺难的,特别是第二种操作,把p移到q的集合,看别人的代码就是p是根的时候怎样怎样,不是根的时候怎样怎样,看不懂~~

但是仔细一想,如果把第i个节点的根变为i+100000就什么都解决了~~~~

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
#include<set>
using namespace std;

#define mxn 210000
#define ym 100200
#define inf 0x3f3f3f3f
#define eps 1e-8
#define LL long long 
#define ULL unsigned long long
#define MP make_pair

int fa[mxn], cnt[mxn];
LL sum[mxn];
int n, m;
int find( int x ) {
	if( fa[x] != x )
		fa[x] = find( fa[x] );
	return fa[x];
}
void init() {
	memset( sum, 0, sizeof( sum ) );
	for( int i = 1; i <= n; ++i )
		fa[i] = i + ym, fa[i+ym] = i + ym, sum[i+ym] = i, cnt[i+ym] = 1;
}
int main() {
	while( scanf( "%d%d", &n, &m ) != EOF ) {
		init();
		int type, p, q;
		for( int i = 1; i <= m; ++i ) {
			scanf( "%d", &type );
			scanf( "%d", &p );
			if( type == 1 ) {
				scanf( "%d", &q );
				int u = find( p );
				int v = find( q );
				if( v == u )
					continue;
				fa[v] = u;
				sum[u] += sum[v];
				cnt[u] += cnt[v];
			}
			if( type == 2 ) {
				scanf( "%d", &q );
				int u = find( p );
				int v = find( q );
				fa[p] = v;
				cnt[u]--;
				sum[u] -= p;
				sum[v] += p;
				cnt[v] ++;
			}
			if( type == 3 ) {
				int u = find( p );
				printf( "%d %lld\n", cnt[u], sum[u] );
			}
		}
	}
	return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值