题目大意:n堆积木,两种操作
1.将x所在的那堆积木移动到y所在的积木之上
2.求所在积木中在x下面的积木的数量
题解:带权并查集
f[x]=y表示x在y上面,即最下面的为根,记录sum[x]表示x所在堆元素个数,维护h[x]表示x到根的距离,也就是询问的答案,然后搞搞就行了
我的收获:带权并查集吼啊
#include <cstdio>
#include <iostream>
#include <vector>
using namespace std;
const int M=30000;
int m,f[M+5],sum[M+5],h[M+5];
int F(int x)
{
if(x==f[x]) return x;
int t=f[x];
f[x]=F(f[x]);
h[x]+=h[t];//更新下这个
return f[x];
}
void merge(int x,int y)
{
int p=F(x),q=F(y);
if(p==q) return ;
f[p]=q;
h[p]=sum[q];//……
sum[q]+=sum[p],sum[p]=0;//……
}
void init()
{
cin>>m;
for(int i=1;i<=M;i++) f[i]=i,sum[i]=1;
char opt[5];int x,y;
while(m--){
scanf("%s",opt);
if(opt[0]=='M') scanf("%d%d",&x,&y),merge(x,y);
else scanf("%d",&x),F(x),printf("%d\n",h[x]);//注意要find一次
}
}
int main()
{
init();
return 0;
}