并查集之删除节点。。。
真的不想再天天做并查集了。。
这题目真是做不完。。
这一道一来又不会。。。
删除节点呢,具体的过程比较复杂,为了简单起见,
我们开始给节点初始化时,就给每个节点一个虚父节点
合并、找根的过程都不影响
而删除的时候,就把要删除的节点指向无意义的点
这样消失的不知不觉 也不会影响跟自己有关系的点。。。
#include <iostream> #include <cstring> #include <string> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <map> #define inf 0x3f3f3f3f #define ll __int64 using namespace std; int r[1200005],vis[1200050],n,m; int root(int a) { if(r[a]==a) return a; r[a]=root(r[a]); return r[a]; } void merge(int a,int b) { int ra,rb; ra=root(a); rb=root(b); if(ra==rb) return ; if(ra<rb) r[ra]=rb; else r[rb]=ra; } int main() { int cnt=0,i,a,b,tmp,p,ans; char s[10]; while(scanf("%d%d",&n,&m)&&(n||m)) { cnt++; for(i=0;i<n;i++) r[i]=i+n; for(i=n;i<n+n+m;i++) r[i]=i; p=n+n; while(m--) { scanf("%s",s); if(s[0]==‘M‘) { scanf("%d%d",&a,&b); merge(a,b); } else { scanf("%d",&a); r[a]=p++; } } ans=0; memset(vis,0,sizeof vis); for(i=0;i<n;i++) { tmp=root(i); if(!vis[tmp]) { ans++; vis[tmp]=1; } } printf("Case #%d: %d\n",cnt,ans); } return 0; }
hdu2473 Junk-Mail Filter 设虚父结点删除节点,布布扣,bubuko.com
hdu2473 Junk-Mail Filter 设虚父结点删除节点
原文:http://blog.csdn.net/u011032846/article/details/21118297