• 货车运输(最大生成树+倍增)


    题面

    原题

    Solution

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    #include<iostream>
    #include<queue>
    #include<algorithm>
    #define ll long long
    #define re register
    using namespace std;
    inline int gi(){
        int f=1,sum=0;char ch=getchar();
        while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
        return f*sum;
    }
    const int N=10010,M=50010;
    int to[M<<1],nxt[M<<1],w[M<<1],front[N],cnt;
    int dep[N],f[N][20],val[N][20],father[N],n,m;
    struct E{
        int u,v,w;
    }edge[M];
    void Add(int u,int v,int W){
        to[++cnt]=v;nxt[cnt]=front[u];front[u]=cnt;
        w[cnt]=W;
    }
    void dfs(int u,int fa){
        dep[u]=dep[fa]+1;f[u][0]=fa;
        for(re int i=front[u];i;i=nxt[i]){
            int v=to[i];
            if(v!=fa){
                val[v][0]=w[i];
                dfs(v,u);f[v][0]=u;
            }
        }
    }
    int lca(int u,int v){
        int ans=2e9;
        if(dep[u]<dep[v])swap(u,v);
        for(int i=15;~i;--i)
            if(dep[u]-(1<<i)>=dep[v]){
                ans=min(ans,val[u][i]);
                u=f[u][i];
            }
        if(u==v)return ans;
        for(re int i=15;~i;i--)
            if(f[u][i]!=f[v][i]){
                ans=min(ans,min(val[v][i],val[u][i]));
                u=f[u][i],v=f[v][i];
            }
        ans=min(ans,min(val[u][0],val[v][0]));
        return ans;
    }
    int find(int x){
        if(father[x]!=x)father[x]=find(father[x]);
        return father[x];
    }
    bool cmp(E a,E b){
        return a.w>b.w;
    }
    int main(){
        n=gi();m=gi();
        for(re int i=1;i<=m;i++){
            int u=gi(),v=gi(),w=gi();
            edge[i]=(E){u,v,w};
        }
        sort(edge+1,edge+m+1,cmp);
        for(re int i=1;i<=n;i++)father[i]=i;
        for(re int i=1;i<=m;i++){
            int u=find(edge[i].u),v=find(edge[i].v);
            if(u!=v){
                father[v]=u;
                Add(edge[i].u,edge[i].v,edge[i].w);
                Add(edge[i].v,edge[i].u,edge[i].w);
            }
        }
        for(re int i=1;i<=n;i++)
            if(!f[i][0]){
                dfs(i,i);val[i][0]=2e9;f[i][0]=i;
            }
        for(re int i=1;i<=15;i++)
            for(re int j=1;j<=n;j++){
                f[j][i]=f[f[j][i-1]][i-1];
                val[j][i]=min(val[f[j][i-1]][i-1],val[j][i-1]);
            }
        int q=gi();
        while(q--){
            int u=gi(),v=gi();
            if(find(u)!=find(v)){
                printf("%d
    ",-1);continue;
            }
            printf("%d
    ",lca(u,v));
        }
        return 0;
    }
    
  • 相关阅读:
    Ubuntu 14.04 FTP服务器--vsftpd的安装和配置
    Python IDE专用编辑器PyCharm下载及配置安装过程(Ubuntu环境)
    Ubuntu Server14.04 32位安装odoo8.0简单方法
    js打印出对象的方法
    odoo中pos模块由于删除partner导致发生(你试图访问的单据已经删除)错误的解决方法
    django的安装和搭建
    mongodb入门
    js数组的操作
    mongodb的优缺点
    Spring动态切换多数据源解决方案
  • 原文地址:https://www.cnblogs.com/cjgjh/p/9867635.html
Copyright © 2020-2023  润新知