http://poj.org/problem?id=1988
#pragma warning (disable:4786)
#include<iostream>
#include<stdio.h>
using namespace std;
int father[30003];
int sum[30003];
int rank[30003]; //离根节点的距离,可以看成树形人事结构图的职位高低-.-
int findSet(int x){
if(father[x]==x||father[x]==-1){
father[x]=x;
return x;
}
else{
int t=findSet(father[x]);
rank[x]+=rank[father[x]]; //在路径压缩的时候更新排名
father[x]=t;
return t;
}
}
void Union(int a,int b){ //合并
a=findSet(a);
b=findSet(b);
father[b]=a;
if(sum[a]==0)
sum[a]=1;
if( sum[b]==0 )
sum[b]=1;
rank[b]=sum[a]; //为什么这个开始会忘了加,晕死
sum[a]+=sum[b];
}
int main()
{
int p,i,a,b;
char ch;
cin>>p;
memset(sum,0,sizeof(sum));
memset(rank,0,sizeof(rank));
memset(father,-1,sizeof(father));
while(p--){
cin>>ch;
if(ch=='M'){
scanf("%d %d",&a,&b);
Union(a,b);
}
else if(ch=='C'){
scanf("%d",&a);
b=findSet(a);
if(sum[b]==0)
sum[b]=1;
printf("%d\n",sum[b]-rank[a]-1); //求的不是离根节点的距离
}
}
}
并查集常作为另一种复杂的数据结构或者算法的存储结构。常见的应用有:求无向图的连通分量个数,最近公共祖先(LCA),带限制的作业排序,实现Kruskar算法求最小生 成树等。明天会更新有关LCA的内容~~