有1~n艘战舰,编号分别是1~n。开始,第i号战舰在第i列上。
有m条命令,命令一共包含2种:
1、M ij,将i号战舰所在的列的全部战舰,保持原有顺序接到第j列战舰后面;
2、Cij,查询第i号战舰和第i号战舰是否在同一列,如果是中间间隔多少搜战舰。 (如果不在同一列,输出-1)n<=30000.m<500000
输入:
10 4
2 3
4 5
4 8
5 8
输出:
7
#include<bits/stdc++.h>
using namespace std;
int fa[30010]; //祖先节点
int dis[30010]; //到根节点的距离
int size[30010];//每一列的战舰数量
int find(int x){
if(fa[x]==x){
return x;
}
int pre=fa[x]; //x的直属父节点
int t=find(fa[x]);
fa[x]=t;
dis[x]+=dis[pre];
return t;
}
void merge(int a,int b){ //a向b合并
int fx=find(a);
int fy=find(b);
if(fx!=fy){
fa[fx]=fy;
}
}
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
fa[i]=i;
size[i]=1;
}
char ch;
int x,y;
for(int i=1;i<=m;i++){
cin>>ch>>x>>y;
int fx=find(x);
int fy=find(y);
if(ch=='M'){ //x移动到y之后 x向y合并
merge(fx,fy);
dis[fx]=size[fy];
size[fy]+=size[fx];
}else{
if(fx==fy){
cout<<abs(dis[x]-dis[y])-1<<endl;
}else{
cout<<-1<<endl;
}
}
}
return 0;
}