洛谷UVA11987Almost Union-Find题解--并查集的删除

题目链接

https://www.luogu.org/problemnew/show/UVA11987

分析

分析下操作发现就是加了个删除操作的并查集,怎么做删除操作呢.

我们用一个\(id[]\)记录每个数字在并查集中的编号,\(tot=n\),一开始\(id[i]=i\),当将\(p\)从原集合中删除时,让原来的\(id[p]\)变成一个虚点,\(id[p]=++tot\),这样就完成了删除操作,当然我们查找祖先时需要\(find(id[x])\)

推荐博客:https://blog.csdn.net/grimcake/article/details/77115078

代码

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cctype>
#include <iostream>
#include <cmath>
#define ll long long 
#define ri register int 
using namespace std;
const int maxn=200005;
const int inf=0x7fffffff;
template <class T>inline void read(T &x){
   x=0;int ne=0;char c;
   while(!isdigit(c=getchar()))ne=c=='-';
   x=c-48;
   while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48;
   x=ne?-x:x;
   return ;
}
int size[maxn],id[maxn],sum[maxn],fa[maxn],tot=0;
int find(int x){
   return fa[x]==x?fa[x]:fa[x]=find(fa[x]);
}
int n,m;
int main(){
   int opt,p,q,x,y;
   while(scanf("%d %d",&n,&m)!=EOF){
       tot=n;
       for(ri i=1;i<=n;i++){
           size[i]=1;
           fa[i]=id[i]=sum[i]=i;
       }
       while(m--){
           read(opt);
           if(opt==1){
               read(p),read(q);
               p=find(id[p]),q=find(id[q]);
               if(p==q)continue;
               fa[p]=q;
               sum[q]+=sum[p];
               size[q]+=size[p];
           }
           else if(opt==2){
               read(p),read(q);
               x=find(id[p]),y=find(id[q]);
               if(p==q)continue;
               id[p]=++tot;
               fa[id[p]]=y;
               sum[y]+=p,size[y]++;
               size[x]--,sum[x]-=p;
           }
           else{
               read(p);
               x=find(id[p]);
               printf("%d %d\n",size[x],sum[x]);
           }
       }
   }
   return 0;
}

转载于:https://www.cnblogs.com/Rye-Catcher/p/9325410.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值