有木有很吊
加强
加强版 啊 ,看了都不敢做了 ,后来先做了食物链这个我还是看过的,但还是A不掉,没明白神魔意思 ,总而言之,大牛的博客是个好东西,我就那么看了一下,还是不懂怎莫办啊,哎,就那样就A掉了。。。。。。。
今天我们来谈一下这个并查集的删除操作,根据我对大牛的理解啊,这个并查集的删除操作并不是把原来的节点删除掉,而是用一个替身替掉,现在的这个点只是用作桥梁的作用,即是无用的,del ,,,del ,,,,删除,那些被删掉的就从n开始给他们一个地址,然后即如下代码所示
#include <stdio.h> #include <string.h> #define N 100001 #define M 1000001 int par[N+M+50]; int repplace[N+50]; int flag[N+M]; int ind; void init(int n ) { for(int i=0;i<n;i++) { par[i]=i; repplace[i]=i; } ind =n; } int findset(int n) { if(n==par[n]) return n; else return par[n]=findset(par[n]); } void unite(int n,int m) { int pn=findset(n); int pm=findset(m); if(pn!=pm) par[pn]=pm; } void Delete(int n)//删除操作, { repplace[n]=ind; par[ind]=ind; ind++; } int main() { int a,b; char s[3]; int x,y; int cas=0; while(scanf("%d%d",&a,&b)==2)//我一直纠结为什莫会WA,判断输入的控制条件错了 { if(a==0&&b==0) break; init(a); for(int i=0;i<b;i++) { scanf("%s",s); if(s[0]=='M') { scanf("%d%d",&x,&y); unite(repplace[x],repplace[y]); } else { scanf("%d",&x); Delete(x); } } memset(flag,0,sizeof(flag)); int ans=0; for(int i=0;i<a;i++)//判断他们有几个集合 { int hh=findset(repplace[i]); if(!flag[hh]) { flag[hh]=1; ans++; } } printf("Case #%d: %d\n",++cas,ans); } }
其它就不做介绍了,只要会并查集的一般能看懂看懂,看不懂可评论,或发私信。。。。。。
Hdu 2473(并查集删除操作) Junk-Mail Filter,布布扣,bubuko.com
时间: 2024-10-16 15:04:32