并查集的变式题
(⊙o⊙)…。好像我并不大会表达
还是直接代码吧
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int f[30010],sum[30010],tot[30010];
//f为并查集数组,sum为这个点与他修改之前的父亲之间的飞船个数,包括他父亲
//tot为以这个点为根节点的树的节点个数
int find(int x)
{
if(f[x]==x)
return x;
int p1=f[x],p2=sum[x];//记录路径压缩之前的father和之间的飞船数
f[x]=find(f[x]);
if(p1!=f[x])
sum[x]=p2+sum[p1];//如果father被更改,之间的飞船数也要更改
return f[x];
}
int main()
{
cin.sync_with_stdio(false);
for(int i=1;i<=30010;i++)
{
f[i]=i;
sum[i]=1;
tot[i]=1;//初始化
}
int t;
cin>>t;
char in;
int a,b;
for(int i=1;i<=t;i++)
{
cin>>in>>a>>b;
int f1=find(a),f2=find(b);//先进行路径压缩
if(in=='M')
{
f[f1]=f2;//更改父节点
sum[f1]=tot[f2];//手动更新,因为是接在最后
tot[f2]+=tot[f1];//手动更新以t2为根节点的树的节点个数
}
if(in=='C')
{
if(f1==f2)
{
int p1=sum[a],p2=sum[b];
if(a==f1)
p1=0;
if(b==f2)
p2=0;
printf("%d\n",max(p1-p2,p2-p1)-1);//输出方案,类似于前缀和
continue;
}
printf("-1\n");
}
}
}