并查集

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的内容~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值