T^T OJ 2144 并查集( 并查集... )


**链接:****传送门 **

思路:增加num[] 记录集合中的个数,maxx[] 记录集合中最大值,挺不错的并查集练习题,主要是 unite 函数里如何改变一些东西,挺好的题,能用C尽量不用C++,效率差蛮大的!


/*************************************************************************
    > File Name: tat2144.cpp
    > Author:    WArobot 
    > Blog:      http://www.cnblogs.com/WArobot/ 
    > Created Time: 2017年05月08日 星期一 18时51分08秒
 ************************************************************************/

#include<bits/stdc++.h>
using namespace std;

const int maxn = 1e6+10;
int n,m;
int par[maxn] , num[maxn] , maxx[maxn];
char op[10];

void init(int n){
	for(int i=0;i<=n;i++){
		par[i]  = i;
		num[i]  = 1;
		maxx[i] = i;
	}
}
int find(int x){
	int p , tmp;
	p = x;
	while( x!=par[x] )
		x = par[x];
	while( p!=x ){
		tmp = par[p];
		par[p] = x;
		p = tmp;
	}
	return x;
}
int same(int x,int y){
	return find(x) == find(y) ;
}
void unite(int x,int y){
	int fx = find(x) , fy = find(y);
	if( fx == fy )	return;
	else{
		par[fy] = fx;
		num[fx] += num[fy];
		maxx[fx] = max( maxx[fx] , maxx[fy] );
	}
}
int main(){
	while(~scanf("%d%d",&n,&m)){
		init(n);
		int x , y , set_num = n;
		while(m--){
			getchar();
			scanf("%s",op);
			if( op[0] == 'u'){
				scanf("%d%d",&x,&y);
				if( find(x)!=find(y) ){
					unite(x,y);
					set_num--;
				}
			}
			else if( op[0]=='s' && op[1]=='a'){
				scanf("%d%d",&x,&y);
				if( same(x,y) )	puts("1");
				else			puts("0");
			}
			else if( op[0]=='n' ){
				scanf("%d",&x);
				printf("%d
",num[ find(x) ]);
			}
			else if( op[0] == 'm' ){
				scanf("%d",&x);
				printf("%d
",maxx[ find(x) ]);
			}
			else{
				printf("%d
",set_num);
			}
		}
	}
	return 0;
}
原文地址:https://www.cnblogs.com/WArobot/p/6826859.html