链接:传送门
思路:增加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\n",num[ find(x) ]);
}
else if( op[0] == 'm' ){
scanf("%d",&x);
printf("%d\n",maxx[ find(x) ]);
}
else{
printf("%d\n",set_num);
}
}
}
return 0;
}