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

浙公网安备 33010602011771号