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;
        }
        
    }
} 

 

posted @ 2016-06-22 09:59  FuTaimeng  阅读(242)  评论(0编辑  收藏  举报