pa[i]代表i的father
pre[i]代表i之前有多少个
sum[i]代表i所在的整列有多少个
cc为命令类型,x y为命令参数, fx fy分别为x y的father
当cc==‘M’时,合并x y,因为是把x所在队列放到y所在队列后面,所以要pre[fx]=sum[fy](剩下的pre在find中计算),sum[fy]+=sum[fx]
当cc=='C'时,如果x y在一个集合内,输出abs(pre[x]-pre[y])-1,问的是中间的个数,所以减1。如果x y不在一个集合,输出-1
在find中:
int find(int x){
if(x!=pa[x]){
int tem=find(pa[x]);//先递归
pre[x]+=pre[pa[x]];//x的pre加上pa[x]的。注意这个pa[x]还没有进行路径压缩
pa[x]=tem;//路径压缩
}
return pa[x];
}
代码:
#include<iostream>
#include<cstring>
#include<cstdlib>
#define Size 30005
using namespace std; int n;
int pa[Size];
int sum[Size],pre[Size];
void init(){
for(int i=;i<Size;i++)pa[i]=i,sum[i]=;
}
int find(int x){
if(x!=pa[x]){
int tem=find(pa[x]);
pre[x]+=pre[pa[x]];
pa[x]=tem;
}
return pa[x];
}
bool query(int x,int y){
return find(x)==find(y);
}
void un(int x,int y){
if(query(x,y))return;
pa[find(x)]=find(y);
} int main(){
init();
int T;cin>>T;
char cc; int x,y;
while(T--){
cin>>cc>>x>>y;
int fx=find(x); int fy=find(y);
if(cc=='M'){
un(x,y);
pre[fx]=sum[fy];
sum[fy]+=sum[fx];
}
else{
if(fx==fy)cout<<abs(pre[x]-pre[y])-<<endl;
else cout<<-<<endl;
} }
}