const int N=120; int father[N]; int rank1[N]; void init(int Size) { for(int i=1;i<=Size;++i) father[i]=i,rank1[i]=0; } int Find(int x) { while(x!=father[x]) x=father[x]; return x; } bool Union(int x,int y) { int fx,fy; fx=Find(x),fy=Find(y); if(fx==fy) return false; else if(rank1[fx]>=rank1[fy]) { father[fy]=fx; rank1[fx]+=rank1[fy]; } else { father[fx]=fy; rank1[fy]+=rank1[fx]; } return true; }
int Find(int x) { return x==f[x]?x:f[x]=Find(f[x]); } void Union(int x,int y) { x=Find(x),y=Find(y); if(x!=y) f[x]=y; }
并查集的删除节点操作
HDU-2473 Junk-Mail Filter
#include <iostream> #include<algorithm> #include <cstdio> #include <cstdlib> #include <cstring> #include <queue> #include<map> #include<set> #include<sstream> #define INF 0x3f3f3f3f #define DOF 0x7f7f7f7f #define mem(a,b) memset(a,b,sizeof(a)) #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); typedef long long ll; using namespace std; const int maxn=2e6+10; int f[maxn],b[maxn],vis[maxn];//令一新数组表示儿子节点的值 int n,m; int Find(int x){ return f[x]==x?x:f[x]=Find(f[x]); } void Union(int x,int y) { x=Find(x),y=Find(y); if(x!=y) f[x]=y; } int main() { int cas=0; while(~scanf("%d%d",&n,&m)&&n){ mem(vis,0); int cnt=n; for(int i=0;i<n;++i) f[i]=b[i]=i; char ch;int a,c; for(int i=1;i<=m;++i){ getchar(); scanf("%c",&ch); if(ch=='M'){ scanf("%d%d",&a,&c); Union(b[a],b[c]); } else{ scanf("%d",&a); f[cnt]=cnt;//将此节点指向外部数组,此数组代表此点的父节点位置 b[a]=cnt; ++cnt; } } ll ans=0; for(int i=0;i<n;++i){ int t=Find(b[i]); if(!vis[t]){ vis[t]=1;++ans; } } printf("Case #%d: %lld ",++cas,ans); } }