题目链接:https://www.jisuanke.com/course/615/28116
题目大意:通过一系列的合并操作,然后求解出两点之间的距离。
题目思路:我们可以很容易的统计俩张卡片是否在同一个队列中,用并查集就可以了。关键是怎么计算,在一个队列中的俩个卡片之间卡片数目,只要维护一下每个卡片到队列头的卡片数目就好了。在计算同一队列中的俩个卡片之间卡片数目,只要把俩个卡片到队列头的卡片数目做差就可以了。
学到的东西:加权并查集。
代码:
//加权并查集模板题,需要整理
#include <bits/stdc++.h>
using namespace std;
const int maxn=5e6+2;
int pre[maxn];
int val[maxn];//存储到根节点距离的数组
int Size[maxn];//存储在该节点下集合的大小
void build(int n)
{
for(int i=0;i<=n;i++)
pre[i]=i,val[i]=0,Size[i]=1;
}
int find(int x)
{
if(pre[x]==x) return x;
int y=pre[x];
pre[x]=find(y);
val[x]+=val[y];//x到根节点的距离就等本身加上双亲到根节点的距离
return pre[x];
}
bool join(int x,int y)
{
int p=find(x);
int q=find(y);
if(p!=q){
pre[p]=q;
//val[q]+=val[p];
val[p]=Size[q];//p到根节点的位置,就等于q集合的大小
Size[q]+=Size[p];//q集合的大小增加了,p集合加入了进来
return true;
}
return false;
}
int main()
{
int n;scanf("%d",&n);
build(n);
while(n--){
char c;
int x,y;
cin>>c>>x>>y;
if(c=='M'){
join(x,y);
}
else{
if(find(x)!=find(y)) cout<<"-1"<<endl;
else cout<<abs(val[x]-val[y])-1<<endl;
}
}
return 0;
}