题目链接:
http://poj.org/problem?id=1988
解题思路:
有很多个stack,一开始每个stack里面都有一个cube。
然后支持两种操作:
1.move x y: 将x所在的stack移动到y所在stack的顶部;
2.count x:查询在x所在stack中,在x之下的cube的个数。
算法思想:
带权的并查集。
设两个权值cnt[x],dis[x]分别代表以x为根结点的堆的碟子的个数和值为x的碟子到根结点的距离。
求x下面有多少碟子就等于cnt[pa[x]] - dis[x] - 1;
AC代码:
#include <iostream>
#include <cstdio>
using namespace std;
const int N = 30005;
int pa[N];
int dis[N];
int cnt[N];
int findset(int x){
if(x == pa[x])
return pa[x];
int root = findset(pa[x]);
dis[x] += dis[pa[x]];
pa[x] = root;
return pa[x];
}
int main(){
int p;
while(~scanf("%d",&p)){
char op[5];
int a,b;
for(int i = 1; i <= N; i++){
pa[i] = i;
cnt[i] = 1;
dis[i] = 0;
}
while(p--){
scanf("%s",op);
if(op[0] == 'M'){
scanf("%d%d",&a,&b);
a = findset(a);
b = findset(b);
if(a != b){
pa[b] = a;
dis[b] = cnt[a];
cnt[a] += cnt[b];
}
}
else{
scanf("%d",&a);
b = findset(a);
printf("%d\n",cnt[b]-dis[a]-1);
}
}
}
return 0;
}