P5092 [USACO04OPEN]Cube Stacking
题目
带权并查集板子题
将立方柱最下面的方块作为该立方柱的祖先
d i s [ i ] 代表方块 i 所在的立方柱上,方块i离它的祖先有多远
f [ i ] 代表方块 i 的祖先
s i z e [ i ] 代表以 i 为祖先立方柱的高度
初始化:
s i z e [ i ] = 1
f [ i ] = i
d i s [ i ] = 0
#include <bits/stdc++.h>
using namespace std;
int f[1000005],dis[1000005],size[1000005];
int read()
{
int x=0,f=1;char ch=getchar();
while (!isdigit(ch)){if (ch=='-')f=-1;ch=getchar();}
while (isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int find(int x)
{
if (f[x]==x)//找到祖先
return x;
int fx=find(f[x]);//fx为x所属立方柱的祖先
dis[x]+=dis[f[x]];//自然:x到祖先的长度为它到它爸爸的距离加它爸爸到祖先的距离
return f[x]=fx;//路径压缩
}
int main()
{
int p=read();
for (int i=1;i<=1000000;i++)
f[i]=i,size[i]=1;//初始化
while (p--)
{
char c;
cin>>c;
if (c=='M')
{
int x=read(),y=read();
int fx=find(x),fy=find(y);
f[fx]=fy;//x祖先的父亲变为y的祖先
dis[fx]+=size[fy];//更新x祖先到该立方柱祖先的距离
size[fy]+=size[fx];//更新该立方柱的高度
}
if (c=='C')
{
int x=read();
find(x);//!!!记住查询时一定要记得更新一下改子节点的信息
printf("%d\n",dis[x]);
}
}
return 0;
}