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
题意:
通过挪动完一些方块, 求某个方块下面有多少方块。
思路:
一开始学并查集, 这题根本不会啊, 上网搜了题解, 虽然照着改对了, 但是根本不会啊。 。。
这不才拿出来研究一下。
通过建一个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;
}