您的位置:首页 > 其它

UVA 11987 Almost Union-Find(并查集)

2014-03-17 18:46 357 查看
本来觉得挺难的,特别是第二种操作,把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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: