Cube Stacking P0J 1988(加權並查集)
阿新 • • 發佈:2018-10-28
ati initial mil ide art else display ans size
Write a program that can verify the results of the game.
* 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.
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.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.
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(加權並查集)