poj 1988 Cube Stacking

// 题意:有n个编号[1,n]的箱子,将每个箱子当做一个栈,有两种操作:
// M a b: 表示将 编号为 a 的箱子所在的栈 放在 编号为 b 的箱子所在栈 的 栈顶 .
// C a: 计算编号为a的所表示的栈中在a号箱子下面的箱子数目.

#include <iostream> //并查集
using namespace std;
#define maxn 30002
int p[maxn],num[maxn],under[maxn];
// num[i] 表示编号为i所在的集合(栈)的元素个数
// under[i] 表示编号为i的节点到其根节点的路径上的元素个数(除了它本身),即在它下方有多少个元素
// 注意根节点在栈底,而不是在栈顶,即栈中元素的父亲节点位于它下方

void init()
{
for(int i=1;i<maxn;++i)
{
p[i]=i;
under[i]=0;
num[i]=1;
}
}
int find(int a)
{
if(p[a]!=a)
{
int t=p[a];
p[a]=find(p[a]);
under[a]+=under[t]; //更新元素与新根节点的距离
}
return p[a];
}

// 将 编号为 a 的箱子所在的栈A 放在 编号为 b 的箱子所在栈B 的 栈顶 ,
// x ,y 分别是 栈A 和 栈B 的栈底元素,则 x 的根节点是 y
void Union(int a,int b)
{
int x=find(a),y=find(b);
p[x]=y;
under[x]=num[y];
num[y]+=num[x];
}
int main()
{
init();
int op;
cin>>op;
while(op--)
{
char ch[2];
int a,b;
scanf("%s",ch);
if(ch[0]=='M')
{
scanf("%d%d",&a,&b);
Union(a,b);
}
else
{
scanf("%d",&a);
find(a);
printf("%d\n",under[a]);
}
}
return 0;
}

posted on 2011-07-22 14:55  sysu_mjc  阅读(137)  评论(0编辑  收藏  举报

导航