zoukankan      html  css  js  c++  java
  • NOIP2013货车运输

    NOIP2013货车运输


    题目描述

    A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路。每一条道路对车辆都有重量限制,简称限重。现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物。

    输入

    第一行有两个用一个空格隔开的整数n,m,表示A国有n座城市和m条道路。接下来m行每行3个整数x、y、z,每两个整数之间用一个空格隔开,表示从x号城市到y号城市有一条限重为z的道路。注意:x不等于y,两座城市之间可能有多条道路。接下来一行有一个整数q,表示有q辆货车需要运货。接下来q行,每行两个整数x、y,之间用一个空格隔开,表示一辆货车需要从x城市运输货物到y城市,注意:x不等于y。
    数据范围:n最大10000,m最大50000,q为30000,z为100000.

    输出

    共有q行,每行一个整数,表示对于每一辆货车,它的最大载重是多少。如果货车不能到达目的地,输出-1。

    样例输入

    4 3
    1 2 4
    2 3 3
    3 1 1
    3
    1 3
    1 4
    1 3

    样例输出

    3
    -1
    3

    做法

    两点之间尽可能大的最小承重路径一定在最大生成树上,于是问题转化为查询最大生成树上,两点之间的最小边的查询,可以倍增,也可以树剖。注意还有可能不能互相到达。

    #include <bits/stdc++.h>
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    typedef long long ll;
    const int N = 10010;
    const int M = 50100;
    const int inf = 0x3f3f3f3f;
    inline int read() {
        char c=getchar(); int x=0,f=1;
        while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
        while(isdigit(c)){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    using namespace std;
    struct edge{int u,v,nxt,w;}E[M<<1],E0[M<<1];
    int h[N],cc;
    void add(int u,int v,int z) {
        E[cc].v=v;E[cc].w=z;E[cc].nxt=h[u];h[u]=cc;++cc;
    }
    bool cmp(edge a,edge b) {return a.w > b.w;}
    int n,m;
    int f[N][22],mn[N][22],fa[N];
    int find(int x) {
        if(x==fa[x])return x;
        return fa[x]=find(fa[x]);
    }
    void merge(int x,int y) {
        x=find(x), y =find(y);
        if(x!=y) fa[x]=y;
    }
    void krus() {
        sort(E0+1,E0+1+m,cmp);
        rep(i,1,m) {
            int tx = find(E0[i].u), ty = find(E0[i].v);
            if(tx!=ty) {
                merge(tx,ty);
                add(E0[i].u,E0[i].v,E0[i].w);
                add(E0[i].v,E0[i].u,E0[i].w);
            }
        }
    }
    bool vis[N];
    int dep[N];
    void dfs(int u,int pre) {
        vis[u] = 1;
        f[u][0] = pre;
        for(int i=h[u];~i;i=E[i].nxt) {
            int v = E[i].v;
            if(!vis[v]&&v!=pre) {
                dep[v]=dep[u]+1;
                mn[v][0] = E[i].w;
                dfs(v,u);
                for(int j=1;j<=20;++j) f[v][j] = f[f[v][j-1]][j-1];
                for(int j=1;j<=20;++j) mn[v][j] = min(mn[v][j-1],mn[f[v][j-1]][j-1]);
            }
        }
    }
    void init() {
        memset(mn,inf,sizeof(mn));
        krus();
        rep(i,1,n)if(!vis[i])dfs(i,0);
    //    rep(i,1,n) {
    //        printf("%d :
    ",i);
    //        printf("dep[%d] = %d
    ",i,dep[i]);
    //        rep(j,0,3) printf("fa[%d][%d] = %d
    ",i,j,f[i][j]);
    //        rep(j,0,3) printf("mn[%d][%d] = %d
    ",i,j,mn[i][j]);
    //    }
    }
    int lca(int x,int y) {
        if(dep[x] > dep[y]) swap(x,y);
        int tx=x,ty=y;
        for(int d=dep[y]-dep[x],i=0;d;d>>=1,++i) if(d&1) ty = f[ty][i];
        if(tx == ty) return tx;
        for(int i=20;i>=0;--i) {
            if(f[tx][i]==f[ty][i]) continue;
            tx = f[tx][i], ty = f[ty][i];
        }
        return f[tx][0];
    }
    int ask_mn(int x,int p) {
        int ans = inf, tx=x;
        for(int d=dep[x]-dep[p],i=0;d;d>>=1,++i) if(d&1) {
            ans = min(ans,mn[tx][i]);
            tx = f[tx][i];
        }
        return ans;
    }
    int ask(int x,int y) {
        if(find(x)!=find(y)) return -1;
        int LCA = lca(x,y);
        return min(ask_mn(x,LCA),ask_mn(y,LCA));
    }
    int main() {
        n = read(), m =read();
        rep(i,1,n) h[i]=-1,fa[i]=i;
        rep(i,1,m) E0[i].u=read(),E0[i].v=read(),E0[i].w=read();
        init();
    
        int q = read();
        while(q--) {
            int x=read(), y =read();
            printf("%d
    ",ask(x,y));
        }
        return 0;
    }
    //9 8
    //1 2 4
    //1 5 3
    //2 3 3
    //2 4 2
    //3 9 2
    //3 8 7
    //5 7 6
    //5 6 7
    
    
  • 相关阅读:
    ssh登录 The authenticity of host 192.168.0.xxx can't be established. 的问题
    linux系统之间互传文件
    Ubuntu16.04上Docker的安装及基本用法
    Ubuntu git 与 gitlab 关联
    Ubuntu E: Sub-process /usr/bin/dpkg returned an error code (1)
    ubuntu16.04搭建jdk1.8运行环境
    Ubuntu18.04 安装Tomcat 8.5
    VMware Ubuntu安装详细过程
    Ubuntu 14.04远程登录服务器--ssh的安装和配置
    Java中文编程开发,让Java编写更改复杂
  • 原文地址:https://www.cnblogs.com/RRRR-wys/p/9384040.html
Copyright © 2011-2022 走看看