code1540 银河英雄传说

Posted FuTaimeng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;
        }
        
    }
} 

 

以上是关于code1540 银河英雄传说的主要内容,如果未能解决你的问题,请参考以下文章

并查集银河英雄传说

P1196 [NOI2002] 银河英雄传说(并查集)

银河英雄传说 - 带权并查集

[luoguP1196] 银河英雄传说(并查集)

P1196 [NOI2002]银河英雄传说

银河英雄传说(带权并查集)