FZU 2155 删点并查集

题意:就是纯裸的合并和删除一个点,和前两天hdu上的一题一样


解法:设立虚拟节点就好了 我们把点0作为所有只有单身节点的根 然后点0的节点个数当然是1 其他的话全部采用虚拟节点

#include<algorithm>
#include<stdio.h>
#include<cstdio>
using namespace std;
#define maxn 2222222
int f[maxn],co[maxn];
int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
int main(){
    
    char op[10];
    int n,m,a,b,x,y,_=1;
    while(~scanf("%d%d",&n,&m)){
        if(!n&&!m)break;
        memset(co,0,sizeof co);
        memset(f,0,sizeof f);
        co[0]=1;
        int cnt=n,ans=n;
        while(m--){
            scanf("%s",op);
            if(*op=='M'){
                scanf("%d%d",&a,&b);++a;++b;
                x=find(a);y=find(b);
                 if(x!=y||x==0||y==0){
                    ++cnt;--ans;
                     f[cnt]=cnt;co[cnt]=0;
                    if(x){
                        f[x]=cnt;co[cnt]+=co[x];
                    }else {
                        f[a]=cnt;co[cnt]++;
                    }
                    if(y){
                        f[y]=cnt;co[cnt]+=co[y];
                    }else{
                        f[b]=cnt;co[cnt]++;
                    }
                 }
            }else if(*op=='S'){
                scanf("%d",&a);++a;
                x=find(a);
                if(co[x]==1||x==0)continue;
                ans++;co[x]--;f[a]=0;
            }
        }
        printf("Case #%d: %d\n",_++,ans);
        
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值