[bzoj3376] Cube Stacking 方块游戏
Description
约翰和贝茜在玩一个方块游戏.编号为1到n的n(1≤n≤30000)个方块正放在地上.每个构成一个立方柱.
游戏开始后,约翰会给贝茜发出P(1≤P≤100000)个指令.指令有两种:
-
移动(M):将包含X的立方柱移动到包含Y的立方柱上.
-
统计(C):统计名含X的立方柱中,在X下方的方块数目.
写个程序帮贝茜完成游戏.
Input
第1行输入P,之后P行每行输入一条指令.形式为“M X Y”或者“C X”
输入保证不会有将立方柱放在自己头上的指令.
Output
每一行,对于每个统计指令,输出其结果.
Sample Input
6
M 1 6
C 1
M 2 4
M 2 6
C 3
C 4
Sample Output
1
0
2
Source
[Usaco2004 Open]
题解
带权并查集:用\(f1[x]\)代表\(x\)最上面的方块编号,用\(f2[x]\)代表\(x\)最下面的方块编号,用\(dis[x]\)代表\(x\)距离最上面的方块的距离,\(dis[f2[x]]-dis[x]\)即为答案。
#include<bits/stdc++.h>
using namespace std;
const int N=30001;
int f1[N],f2[N],dis[N];
int Find(int x)
{
if(x!=f1[x])
{
int Res=f1[x];
f1[x]=Find(Res),
f2[x]=f2[Res],
dis[x]+=dis[Res];
}
return f1[x];
}
void Union(int x,int y)
{
int f1x=Find(x),f1y=Find(y);
f1[f1y]=f1x,dis[f1y]=dis[f2[x]]+1,f2[f1x]=f2[f1y];
Find(f2[y]);
}
int main()
{
int P,x,y; char c;
for(int i=1;i<N;++i) f1[i]=f2[i]=i;
for(scanf("%d\n",&P);P;--P)
{
scanf("%c",&c);
if(c=='M') scanf("%d%d\n",&x,&y),Union(x,y);
else scanf("%d\n",&x),Find(x),printf("%d\n",dis[f2[x]]-dis[x]);
}
return 0;
}
本文作者:OItby @ https://www.cnblogs.com/hihocoder/
未经允许,请勿转载。