zoukankan      html  css  js  c++  java
  • 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;
            }
            
        }
    } 
  • 相关阅读:
    ApiKernel
    ApiUser
    BringWindowToTop完美激活窗口与置顶
    poj2486 Apple Tree【区间dp】
    HYSBZ1588 营业额统计【Splay】
    hdu5115 Dire Wolf【区间dp】
    poj1144 Network【tarjan求割点】
    poj1236 Network of Schools【强连通分量(tarjan)缩点】
    poj2342 Anniversary party【树形dp】
    poj2449 Remmarguts' Date【A*算法】
  • 原文地址:https://www.cnblogs.com/FuTaimeng/p/5606074.html
Copyright © 2011-2022 走看看