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

    题目描述

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

    输入输出格式

    输入格式:

    第一行有两个用一个空格隔开的整数n,mn,m,表示 AA 国有nn 座城市和 mm 条道路。

    接下来 mm行每行33个整数 x, y, zx,y,z,每两个整数之间用一个空格隔开,表示从 xx号城市到yy号城市有一条限重为 zz 的道路。注意: xx 不等于 yy,两座城市之间可能有多条道路 。

    接下来一行有一个整数 q,表示有 q 辆货车需要运货。

    接下来 q 行,每行两个整数 x、y,之间用一个空格隔开,表示一辆货车需要从 x 城市运输货物到 y 城市,注意:x 不等于 y 。

    输出格式:

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

    根据题目得知,我们可以不用考虑路径有多长,只用考虑是否能到以及经过路径的最大值。

    这样我们可以把原图化简为一个最大生成树,保证原图能到达的点,化简后也能到达。

    然后对于每一个x、y,只用求出它们的路径中间的最小值就可以了。用LCA就行

    但是!我们发现,输入的图不一定是联通的!也就是,我们生成的不一定是最大生成树而是最大生成森林!

    这样,我们跑LCA会原地爆炸!

    故此,我们可以在构建完最大森林后,将所有森林的根节点连到一个虚拟节点0,。

    如果LCA时,发现两个的LCA是0,那么就输出-1.

    #include <iostream>
    #include <cstdio>
    #include <queue>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #define REP(i,k,n) for(int i=k;i<=n;i++)
    #define in(a) a=read()
    #define MAXN 500010
    using namespace std;
    inline int read(){
        int x=0,f=1;
        char ch=getchar();
        for(;!isdigit(ch);ch=getchar())
            if(ch=='-')
                f=-1;
        for(;isdigit(ch);ch=getchar())
            x=x*10+ch-'0';
        return x*f;
    }
    int n,m,p,ans;
    int f[MAXN];
    queue <int> Q;
    int total=0,head[MAXN],to[MAXN<<1],nxt[MAXN<<1],val[MAXN<<1];
    int vis[MAXN],depth[MAXN];
    int tree[MAXN][30],minn[MAXN][30];
    struct node{
        int a,b,c;
    }l[MAXN];
    inline bool cmp(node a,node b){
        return a.c>b.c;
    }
    inline int getf(int k){//并查集求最大生成森林
        if(f[k]==k)  return k;
        return f[k]=getf(f[k]);
    }
    inline void adl(int a,int b,int c){
        total++;
        to[total]=b;
        val[total]=c;
        nxt[total]=head[a];
        head[a]=total;
        return ;
    }
    inline void bfs(){//LCA预处理
        Q.push(0);
        vis[0]=1;
        while(!Q.empty()){
            int u=Q.front();
            Q.pop();
            REP(i,1,18)
                tree[u][i]=tree[tree[u][i-1]][i-1],minn[u][i]=min(minn[u][i-1],minn[tree[u][i-1]][i-1]);
            for(int e=head[u];e;e=nxt[e])
                if(!vis[to[e]]){
                    vis[to[e]]=1;
                    depth[to[e]]=depth[u]+1;
                    tree[to[e]][0]=u;
                    minn[to[e]][0]=val[e];
                    Q.push(to[e]);
                }
        }
        return ;
    }
    inline int lca(int u,int v){//跑LCA
        if(depth[u]<depth[v])  swap(u,v);
        int d=depth[u]-depth[v];
        REP(i,0,18)
            if(d&(1<<i)){
                ans=min(ans,minn[u][i]);
                u=tree[u][i];
            }
        if(u==v)  return u;
        for(int i=18;i>=0;i--)
            if(tree[u][i]!=tree[v][i]){
                ans=min(ans,min(minn[u][i],minn[v][i]));
                u=tree[u][i];
                v=tree[v][i];
            }
        ans=min(ans,min(minn[u][0],minn[v][0]));
        u=tree[u][0];
        v=tree[v][0];
        return u;
    }
    int main(){
        in(n);in(m);
        REP(i,1,n)  f[i]=i;
        REP(i,1,m)
          in(l[i].a),in(l[i].b),in(l[i].c);
        sort(l+1,l+m+1,cmp);
        REP(i,1,m){
            int f1=getf(l[i].a),f2=getf(l[i].b);
            if(f1!=f2){
                adl(l[i].a,l[i].b,l[i].c);
                adl(l[i].b,l[i].a,l[i].c);
                f[f2]=f1;
            }
        }
        REP(i,1,n)//构建虚拟节点
            if(!vis[i]){
                adl(0,i,0);
                bfs();//对于森林里的每一颗树都跑一边预处理
            }
        in(p);
        int u,v;
        REP(i,1,p){
            ans=2147483647;
            in(u),in(v);
            if(lca(u,v))  cout<<ans<<endl;
            else  cout<<"-1"<<endl;
        }
        return 0;
    }
        
  • 相关阅读:
    2017 Multi-University Training Contest
    NTT模板
    重庆OI2017 小 Q 的棋盘
    用TensorFlow2.0构建分类模型对数据集fashion_mnist进行分类
    读取keras中的fashion_mnist数据集并查看
    基本类型和引用类型
    idea快捷键
    pytorch的torch.nn.CrossEntropyLoss()
    高斯模糊和高斯双边滤波
    opencv之模糊操作
  • 原文地址:https://www.cnblogs.com/jason2003/p/9768203.html
Copyright © 2011-2022 走看看