您的位置:首页 > 其它

POJ - 1988 Cube Stacking(带权并查集)

2015-09-13 00:57 399 查看
Cube Stacking

Time Limit: 2000MSMemory Limit: 30000KB64bit IO Format: %I64d & %I64u
Submit Status

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.

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.

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


题意:N个立方体放在N个堆里。有两种操作:
M a b:把a所在的堆移到b所在的堆上,堆本身的顺序不变。
C a:询问a下面有多少个立方体。

开两个数组deep[i]记录i点到根节点的距离,son[i]表示i节点下有多少儿子(包括自己),于是对询问可以得出答案为:
son[root]-deep[i]-1
压缩路径的时候要更新deep的值,合并吧b并到a节点的下面,更新deep和son。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

const int MAXN = 30100;

int fa[MAXN];
int deep[MAXN];
int son[MAXN];

void init()
{
	for (int i = 0; i < MAXN; i++)
	{
		fa[i] = i;
		deep[i] = 0;
		son[i] = 1;
	}
}

int find(int t)
{
	if (fa[t] == t)
		return t;
	int temp = fa[t];
	fa[t] = find(temp);
	deep[t] += deep[temp];
	return fa[t];
}

void Move_A_to_B_top(int a, int b)
{
	int roota = find(a);
	int rootb = find(b);
	if (roota != rootb)
	{
		fa[rootb] = roota;
		deep[rootb] = son[roota]; 
		son[roota] += son[rootb];
	}
}

int main()
{
	char op;
	int a, b;
	int p;
	while (scanf("%d", &p) != EOF)
	{
		init();
		for (int i = 0; i < p; i++)
		{
			cin >> op;
			if (op == 'M')
			{
				scanf("%d%d", &a, &b);
				Move_A_to_B_top(a, b);
			}
			else
			{
				scanf("%d", &a);
				int root = find(a);
				printf("%d\n", son[root] - deep[a] - 1);
			}
		}
	}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: