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\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;
}

转载于:https://www.cnblogs.com/WArobot/p/6826859.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值