Cube Stacking(并差集深度+结点个数)
Cube Stacking
Time Limit: 2000MS | Memory Limit: 30000K | |
Total Submissions: 21567 | Accepted: 7554 | |
Case Time Limit: 1000MS |
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.
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.
* 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个从1到n编号的箱子,将每个箱子当做一个栈,对这些箱子进行p次操作,每次操作分别为以下两种之一:
1>输入 M x y:表示将编号为x的箱子所在的栈放在编号为y的箱子所在栈的栈顶.
2>输入 C x:计算编号为x的所表示的栈中在x号箱子下面的箱子数目.
题解:和龙珠那题一样,坑了半天,写的都醉了。。。
ac代码贴上:
1 #include<stdio.h> 2 #include<string.h> 3 const int MAXN=30010; 4 int pre[MAXN],s[MAXN],dep[MAXN];//s数组存当前树的节点数; 5 int find(int x){ 6 if(x!=pre[x]){ 7 int t=pre[x]; 8 pre[x]=find(pre[x]); 9 dep[x]+=dep[t]; 10 } 11 /* int i=x,j; 12 while(i!=r){ 13 j=pre[i];pre[i]=r;i=j; 14 }*/ 15 return pre[x]; 16 } 17 void merge(int x,int y){ 18 int f1,f2; 19 f1=find(x);f2=find(y); 20 // printf("%d %d\n",f1,f2); 21 if(f1!=f2){ 22 pre[f2]=f1; 23 dep[f2]=s[f1]; 24 s[f1]+=s[f2]; 25 } 26 } 27 int main(){ 28 int N,x,y; 29 char c[5];//定义成s了,错的啊。。。。 30 while(~scanf("%d",&N)){ 31 for(int i=1;i<=N;i++)pre[i]=i,dep[i]=0,s[i]=1; 32 while(N--){ 33 scanf("%s",c); 34 if(c[0]=='M'){ 35 scanf("%d%d",&x,&y); 36 merge(x,y); 37 } 38 else { 39 scanf("%d",&x); 40 int px=find(x); 41 // printf("s[%d]=%d %d\n",px,s[px],dep[x]); 42 printf("%d\n",s[px]-dep[x]-1); 43 } 44 } 45 } 46 return 0; 47 }
另一种解法超时:
1 #include<stdio.h> 2 #include<string.h> 3 const int MAXN=300010; 4 int pre[MAXN],s[MAXN];//s数组存当前树的节点数; 5 int find(int x){ 6 while(x!=pre[x]) 7 x=pre[x]; 8 return x; 9 } 10 void merge(int x,int y){ 11 int f1,f2; 12 f1=find(x);f2=find(y); 13 if(f1!=f2){ 14 pre[f2]=f1; 15 s[f1]+=s[f2]; 16 } 17 } 18 int getdep(int x){ 19 int s=0; 20 while(x!=pre[x]){ 21 x=pre[x]; 22 s++; 23 } 24 return s; 25 } 26 int main(){ 27 int N,x,y; 28 char c[5];//定义成s了,错的啊。。。。 29 while(~scanf("%d",&N)){ 30 for(int i=1;i<=N;i++)pre[i]=i,s[i]=1; 31 while(N--){ 32 scanf("%s",c); 33 if(c[0]=='M'){ 34 scanf("%d%d",&x,&y); 35 merge(x,y); 36 } 37 else { 38 scanf("%d",&x); 39 int px=find(x); 40 int d=getdep(x); 41 printf("%d\n",s[px]-d-1); 42 } 43 } 44 } 45 return 0; 46 }