1. 程式人生 > >Cube Stacking P0J 1988(加權並查集)

Cube Stacking P0J 1988(加權並查集)

ati initial mil ide art else display ans size

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塊方塊,p次操作,每次操作有兩種類型,‘M a b‘ 意思是將含有方塊a的堆挪到b上:‘C a’意思是查詢方塊a下面有幾個方塊。
解題思路:

本題目使用並查集來進行計算。 sum[n]數組來統計當前堆n中方塊個數。 under[n]數組來統計當前n下面的方塊個數。 在進行計算的時候,路徑壓縮和合並均更新under的值。 未進行路徑壓縮的時候,方塊n所記錄的under並非final value, 僅僅只是包含了到root[n]的方塊個數。 通過路徑壓縮的過程,不斷的增加當前n的根節點(遞歸)的under值,求出最終的under值。進行路徑合並的時候,更新sum值和under值。當一個堆放在另一個堆上時,被移動的堆的under值一定為0, 此時更新under值為另一個堆的根的sum值,即計算出了此處的部分under值。然後更新合並堆的sum值



 1 #include<cstdio>
 2 #include<cstring>
 3 #define maxs 30010
 4 using namespace std;
 5 int pre[maxs];
 6 int sum[maxs];
 7 int under[maxs];
 8 void init()
 9 {
10     int i;
11     for(i=0; i<maxs; i++)
12     {
13         pre[i]=i;
14         under[i]=0;
15         sum[i]=1;
16     }
17 }
18 int Find(int x)
19 {
20     int t;
21     if(x==pre[x])
22     {
23         return x;
24     }
25     t=Find(pre[x]);
26     under[x]+=under[pre[x]];
27     pre[x]=t;
28     return pre[x];
29 }
30 void Union(int x,int y)
31 {
32     int a=Find(x);
33     int b=Find(y);
34     if(a==b)
35     {
36         return ;
37     }
38     pre[a]=b;
39     under[a]=sum[b];///將a堆放在b堆之上,更新此時a堆下面的數量
40     sum[b]+=sum[a];///將a堆和b堆合為一個整體,更新整體新堆的數量
41 }
42 
43 int main()
44 {
45     int n;
46     char q;
47     int a,b;
48     scanf("%d",&n);
49     getchar();
50     init();
51     while(n--)
52     {
53         scanf("%c",&q);
54         if(q==M)
55         {
56             scanf("%d%d",&a,&b);
57             getchar();
58             Union(a,b);
59         }
60         else if(q==C)
61         {
62             scanf("%d",&a);
63             getchar();
64             b=Find(a);
65             printf("%d\n",under[a]);
66         }
67     }
68     return 0;
69 }

 

Cube Stacking P0J 1988(加權並查集)