【POJ 1988】 Cube Stacking (带权并查集)
Cube StackingDescription
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 4Sample Output
1 0 2Source
【题意】
约翰和贝西在玩叠积木,每块积木是大小一样的立方体,将几块积木叠在一起可以得到更高的长
方体。积木是有磁性的,叠起来的积木分不开。
约翰负责把积木叠高,而贝西负责清点积木的高度。一开始共有 N 块积木,编号为 1 到 N,所
有积木都是分开的,没有积木叠在一起。
每次移动积木的时候,约翰会先选择一块积木 X,再选择另一块积木 Y,把 X 搬到 Y 的上方。
如果 X 已经和其它积木叠在一起了,那么应将这叠积木整体移动到 Y 的上方;如果 Y 已经和其它积
木叠在一起了的,假设在 Y 上方最高处的积木为 Z,那么应将 X 所在的那叠积木移动到 Z 的上方。
在约翰辛苦劳动的同时,贝西在一边计算积木已经叠得多高了。约翰和贝西是交替工作的,可惜
贝西不太擅长于数数,请你帮她计算一下,在一些时刻,指定的积木的下方还有多少其他积木。
方体。积木是有磁性的,叠起来的积木分不开。
约翰负责把积木叠高,而贝西负责清点积木的高度。一开始共有 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 }
2016-10-27 20:25:21