【POJ 1988】 Cube Stacking (带权并查集)

Cube Stacking

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

Source

 
 
【题意】
  约翰和贝西在玩叠积木,每块积木是大小一样的立方体,将几块积木叠在一起可以得到更高的长
方体。积木是有磁性的,叠起来的积木分不开。
约翰负责把积木叠高,而贝西负责清点积木的高度。一开始共有 N 块积木,编号为 1 到 N,所
有积木都是分开的,没有积木叠在一起。
每次移动积木的时候,约翰会先选择一块积木 X,再选择另一块积木 Y,把 X 搬到 Y 的上方。
如果 X 已经和其它积木叠在一起了,那么应将这叠积木整体移动到 Y 的上方;如果 Y 已经和其它积
木叠在一起了的,假设在 Y 上方最高处的积木为 Z,那么应将 X 所在的那叠积木移动到 Z 的上方。
在约翰辛苦劳动的同时,贝西在一边计算积木已经叠得多高了。约翰和贝西是交替工作的,可惜
贝西不太擅长于数数,请你帮她计算一下,在一些时刻,指定的积木的下方还有多少其他积木。

 
【分析】
  我这个并查集的权值是他跟父亲的距离,最后做一遍find就知道他跟最低点的距离(即下面有多少个东西),然后我还开多了一个并查集,表示这个东西最上面是什么东西。
  差不多这样把。
 
代码如下:
 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 #include<queue>
 7 #include<cmath>
 8 using namespace std;
 9 #define Maxn 300010
10 
11 int fa[Maxn],d[Maxn],g[Maxn];
12 char s[10];
13 
14 int ffind(int x)
15 {
16     int y=fa[x];
17     if(fa[x]!=x) fa[x]=ffind(fa[x]);
18     d[x]+=d[y];
19     return fa[x];
20 }
21 
22 int find_g(int x)
23 {
24     if(g[x]!=x) g[x]=find_g(g[x]);
25     return g[x];
26 }
27 
28 int main()
29 {
30     int q;
31     scanf("%d",&q);
32     for(int i=1;i<=300010;i++) fa[i]=i,g[i]=i,d[i]=0;
33     for(int i=1;i<=q;i++)
34     {
35         scanf("%s",s);
36         if(s[0]=='M')
37         {
38             int x,y;
39             scanf("%d%d",&x,&y);
40             int z=ffind(x);y=find_g(y);
41             fa[z]=y;d[z]=1;
42             g[find_g(y)]=find_g(x);
43         }
44         else
45         {
46             int x;
47             scanf("%d",&x);
48             ffind(x);
49             printf("%d\n",d[x]);
50         }
51     }
52     return 0;
53 }
[POJ 1988]

 

2016-10-27 20:25:21

posted @ 2016-10-27 20:20  konjak魔芋  阅读(580)  评论(0编辑  收藏  举报