并查集:做题的关键是Union和findSet的编写 ,其中还是有章可循的,下面是poj1988的一个题目
// 1988.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include<iostream> using namespace std; int p[30010],rank[30010],size[30010],N; int findSet(int x) { int fa; if(x==p[x]) return x; fa=p[x]; p[x]=findSet(fa); rank[x]+=rank[fa];//更新u值,因为路径压缩后x的父节点发生了变化 return p[x]; } void MakeSet() { for(int i=1;i<30010;i++) { p[i]=i; size[i]=1; rank[i]=0; } } void Union(int x,int y) { int px,py; px=findSet(x); py=findSet(y); if(px==py) return; p[py]=px; rank[py]+=size[px];//更新rank,加上父节点的元素个数即可 size[px]+=size[py];//更新元素个数 } int main() { int a,b,d,px,py,ans; char c; memset(rank,0,30010*sizeof(rank[0])); memset(size,1,30010*sizeof(size[0])); memset(p,0,30010*sizeof(p[0])); cin>>N; MakeSet(); for(int i=0;i<N;i++) { cin>>c; if(c=='M') { cin>>a>>b; Union(a,b); for(int i=1;i<=N;i++) cout<<p[i]<<" "; cout<<endl; for(int i=1;i<=N;i++) cout<<rank[i]<<" "; cout<<endl; for(int i=1;i<=N;i++) cout<<size[i]<<" "; cout<<endl; } else { cin>>d; px=findSet(d); ans=size[px]-rank[d]-1; cout<<ans<<endl; } } system("pause"); return 0; }