code1540 银河英雄传说
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=1;i<Size;i++)pa[i]=i,sum[i]=1; } 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])-1<<endl; else cout<<-1<<endl; } } }