Time Limit: 2000MS | Memory Limit: 30000K | |
Total Submissions: 27031 | Accepted: 9478 | |
Case Time Limit: 1000MS |
Description
Farmer John and Betsy are playing a game with N (1 <= N <= 30,000)identical cubes labeled 1 through N. They start with N stacks, each containing a single cube. Farmer John asks Betsy to perform P (1<= P <= 100,000) operation. There are two types of operations:
moves and counts.
* In a move operation, Farmer John asks Bessie to move the stack containing cube X on top of the stack containing cube Y.
* In a count operation, Farmer John asks Bessie to count the number of cubes on the stack with cube X that are under the cube X and report that value.
Write a program that can verify the results of the game.
moves and counts.
* In a move operation, Farmer John asks Bessie to move the stack containing cube X on top of the stack containing cube Y.
* In a count operation, Farmer John asks Bessie to count the number of cubes on the stack with cube X that are under the cube X and report that value.
Write a program that can verify the results of the game.
Input
* Line 1: A single integer, P
* Lines 2..P+1: Each of these lines describes a legal operation. Line 2 describes the first operation, etc. Each line begins with a 'M' for a move operation or a 'C' for a count operation. For move operations, the line also contains two integers: X and Y.For count operations, the line also contains a single integer: X.
Note that the value for N does not appear in the input file. No move operation will request a move a stack onto itself.
* Lines 2..P+1: Each of these lines describes a legal operation. Line 2 describes the first operation, etc. Each line begins with a 'M' for a move operation or a 'C' for a count operation. For move operations, the line also contains two integers: X and Y.For count operations, the line also contains a single integer: X.
Note that the value for N does not appear in the input file. No move operation will request a move a stack onto itself.
Output
Print the output from each of the count operations in the same order as the input file.
Sample Input
6 M 1 6 C 1 M 2 4 M 2 6 C 3 C 4
Sample Output
1 0 2
Source
问题简述:
有n个箱子,初始时每个箱子单独为一列。有p行输入,每行为M x y或者C x,M x y表示将x箱子所在列箱子搬到y所在列箱子上,C x表示需要输出箱子x下面有多少个箱子。
问题分析:
这是一个用并查集来解的问题。需要两个辅助数组用于计算。
程序说明:
数组cnt1[x]表示x的子树大小。
数组cnt2[x]表示x到根节点的距离。
题记:(略)
参考链接:(略)
AC的C++语言程序如下:
/* POJ1988 Cube Stacking */
#include <iostream>
#include <stdio.h>
using namespace std;
const int N = 1e5;
int f[N + 1];
int cnt1[N + 1], cnt2[N + 1];
void Init()
{
for(int i = 1; i <= N; i++) {
f[i] = i;
cnt1[i] = 1; // 当前列箱子数量
cnt2[i] = 0; // 当前箱子到顶上距离(上面有多少箱子)
}
}
int Find(int a)
{
if(f[a] == a)
return a;
int pa = f[a];
f[a] = Find(f[a]);
cnt2[a] += cnt2[pa];
return f[a];
}
void Union(int a, int b)
{
int pa = Find(a);
int pb = Find(b);
if(pa != pb) {
f[pb] = pa;
cnt2[pb] = cnt1[pa];
cnt1[pa] += cnt1[pb];
}
}
int main()
{
int p;
Init();
scanf("%d", &p);
while(p--) {
char op;
scanf("%*c%c", &op);
if(op == 'M') {
int x, y;
scanf("%d%d", &x, &y);
Union(x, y);
} else if(op == 'C') {
int x;
scanf("%d", &x);
printf("%d\n", cnt1[Find(x)] - cnt2[x] - 1);
}
}
return 0;
}