并查集的题目

并查集:做题的关键是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;
}

posted @ 2011-05-19 19:11  张兰云  阅读(212)  评论(0编辑  收藏  举报