POJ 1988 Cube Stacking

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

题意:

通过挪动完一些方块, 求某个方块下面有多少方块。

思路:

一开始学并查集, 这题根本不会啊, 上网搜了题解, 虽然照着改对了, 但是根本不会啊。 。。

扫描二维码关注公众号,回复: 2746831 查看本文章

这不才拿出来研究一下。

通过建一个h数组,表示到根节点的距离, 然后再建一个num数组, 表示下面共有有多少个节点。

先说一下合并:

合并:(此树是倒着建的)

求出两个子节点的父节点temp1和temp2,

然后将要连接的temp1节点的h[temp1] 等于num[temp2], num[temp2]+=num[temp1];

然后再连接上。

查找:

就是找根节点, 然后压缩路径。 在这期间可以求出到根节点的距离,通过加上父节点到根节点的距离来实现。

代码如下:
 

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn=30005;
int p;
int a[maxn];  
int h[maxn]; //h表示到根节点的距离
int num[maxn];//表示下面有多少节点
int finds (int x)
{
    int par;
    if(a[x]==x)
        return x;
    else
        par=finds(a[x]);
    h[x]=h[a[x]]+h[x];
    a[x]=par;
    return par;
}
void unite(int x,int y)
{
    int temp1=finds(x);
    int temp2=finds(y);
    if(temp1!=temp2)
    {
        h[temp1]=num[temp2];
        num[temp2]+=num[temp1];
        a[temp1]=temp2;
    }
}
int main()
{
    scanf("%d",&p);
    for (int i=1;i<=maxn;i++)
    {
               a[i]=i;
               h[i]=0;
               num[i]=1;
    }
    for (int i=0;i<p;i++)
    {
       char c[10];
       int n;
       scanf ("%s",c);
       if(c[0]=='M')
       {
           int x1,x2;
           scanf("%d%d",&x1,&x2);
           unite(x1,x2);
       }
       else
       {
           int x1;
           scanf("%d",&x1);
           finds(x1);
           printf("%d\n",h[x1]);
       }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41410799/article/details/81515615