题目链接:
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; }