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

    传送门

    题目

    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

    输出格式:

    输出共有 q 行,每行一个整数,表示对于每一辆货车,它的最大载重是多少。如果货

    车不能到达目的地,输出-1。

    分析

    首先,因为我们要让最小边权最大,所以一些较小边是我们不需要的,因此我们要先建一棵最大生成树,而非树边我们便再也不用考虑了。之后我们要进行的便是找x到y的树上简单路径的边权最小值(我们不难想出这样求出的最小值一定是最优的)。对于求LCA我们使用倍增求解就可以,将par数组分成两个,一个记录祖先节点信息,另一个记录到达祖先节点的路径中的边权最小值。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    const int LOG=15;
    struct node {
          int a,b,c;
    }d[110000];
    int par[20][11000][3],dep[110000],fa[110000];
    int cnt,to[210000],head[210000],nxt[210000],w[210000];
    inline void read(int &x){
          int f=1;x=0;char s=getchar();
          while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
          while(s>='0'&&s<='9'){x=(x<<3)+(x<<1)+s-'0';s=getchar();}
          x*=f;
    }
    inline bool cmp(const node &x,const node &y){return x.c>y.c;}
    inline int sf(int x){return fa[x]==x?x:fa[x]=sf(fa[x]);}
    inline void add(int u,int v,int val){
          nxt[++cnt]=head[u],to[cnt]=v,head[u]=cnt,w[cnt]=val;
          nxt[++cnt]=head[v],to[cnt]=u,head[v]=cnt,w[cnt]=val;
    }
    inline void dfs(int x,int pa){
          int i;
          for(i=head[x];i;i=nxt[i])
             if(to[i]!=pa){
                dep[to[i]]=dep[x]+1;dfs(to[i],x);
                par[0][to[i]][0]=x;par[0][to[i]][1]=w[i];
             }
    }
    inline int que(int x,int y){
          int ans=1000000007,i;
          if(dep[x]>dep[y])swap(x,y);
          for(i=LOG;i>=0;i--)
             if(dep[y]-dep[x]>=(1<<i)){
                 ans=min(ans,par[i][y][1]);
                 y=par[i][y][0];
             }
          if(x==y)return ans;
          for(i=LOG;i>=0;i--)
             if(par[i][x][0]!=par[i][y][0]){
                 ans=min(ans,min(par[i][x][1],par[i][y][1]));
                 x=par[i][x][0],y=par[i][y][0];
             }
          ans=min(ans,min(par[0][x][1],par[0][y][1]));
          return ans;
    }
    int main()
    {     int n,m,i,j,k,x,y,sum=0,q;
          read(n),read(m);
          for(i=1;i<=m;i++)read(d[i].a),read(d[i].b),read(d[i].c);
          sort(d+1,d+m+1,cmp);
          for(i=1;i<=n;i++)fa[i]=i;
          for(i=1;i<=m;i++){
               if(sf(d[i].a)!=sf(d[i].b)){
                   fa[sf(d[i].a)]=sf(d[i].b);
                   add(d[i].a,d[i].b,d[i].c);
                   sum++;
               }
          }
          for(i=1;i<=n;i++)
             if(!dep[i]){
                 dep[i]=1;
                 dfs(i,0);
             }
          for(i=0;i<LOG;i++)
             for(j=1;j<=n;j++){
                par[i+1][j][0]=par[i][par[i][j][0]][0];
                par[i+1][j][1]=min(par[i][j][1],par[i][par[i][j][0]][1]);
             }
          read(q);
          for(i=1;i<=q;i++){
               read(x),read(y);
               if(sf(x)!=sf(y)){puts("-1");continue;}
               printf("%d
    ",que(x,y));
          }
          return 0;
    }

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    const int LOG=15;
    struct node {
          int a,b,c;
    }d[110000];
    int par[20][11000][3],dep[110000],fa[110000];
    int cnt,to[210000],head[210000],nxt[210000],w[210000];
    inline void read(int &x){
          int f=1;x=0;char s=getchar();
          while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
          while(s>='0'&&s<='9'){x=(x<<3)+(x<<1)+s-'0';s=getchar();}
          x*=f;
    }
    inline bool cmp(const node &x,const node &y){return x.c>y.c;}
    inline int sf(int x){return fa[x]==x?x:fa[x]=sf(fa[x]);}
    inline void add(int u,int v,int val){
          nxt[++cnt]=head[u],to[cnt]=v,head[u]=cnt,w[cnt]=val;
          nxt[++cnt]=head[v],to[cnt]=u,head[v]=cnt,w[cnt]=val;
    }
    inline void dfs(int x,int pa){
          int i;
          for(i=head[x];i;i=nxt[i])
             if(to[i]!=pa){
                dep[to[i]]=dep[x]+1;dfs(to[i],x);
                par[0][to[i]][0]=x;par[0][to[i]][1]=w[i];
             }
    }
    inline int que(int x,int y){
          int ans=1000000007,i;
          if(dep[x]>dep[y])swap(x,y);
          for(i=LOG;i>=0;i--)
             if(dep[y]-dep[x]>=(1<<i)){
                 ans=min(ans,par[i][y][1]);
                 y=par[i][y][0];
             }
          if(x==y)return ans;
          for(i=LOG;i>=0;i--)
             if(par[i][x][0]!=par[i][y][0]){
                 ans=min(ans,min(par[i][x][1],par[i][y][1]));
                 x=par[i][x][0],y=par[i][y][0];
             }
          ans=min(ans,min(par[0][x][1],par[0][y][1]));
          return ans;
    }
    int main()
    {     int n,m,i,j,k,x,y,sum=0,q;
          read(n),read(m);
          for(i=1;i<=m;i++)read(d[i].a),read(d[i].b),read(d[i].c);
          sort(d+1,d+m+1,cmp);
          for(i=1;i<=n;i++)fa[i]=i;
          for(i=1;i<=m;i++){
               if(sf(d[i].a)!=sf(d[i].b)){
                   fa[sf(d[i].a)]=sf(d[i].b);
                   add(d[i].a,d[i].b,d[i].c);
                   sum++;
               }
          }
          for(i=1;i<=n;i++)
             if(!dep[i]){
                 dep[i]=1;
                 dfs(i,0);
             }
          for(i=0;i<LOG;i++)
             for(j=1;j<=n;j++){
                par[i+1][j][0]=par[i][par[i][j][0]][0];
                par[i+1][j][1]=min(par[i][j][1],par[i][par[i][j][0]][1]);
             }
          read(q);
          for(i=1;i<=q;i++){
               read(x),read(y);
               if(sf(x)!=sf(y)){puts("-1");continue;}
               printf("%d ",que(x,y));
          }
          return 0;
    }

  • 相关阅读:
    IfcQuantityWeight
    IfcPhysicalComplexQuantity
    IfcBinary
    大服务器
    DFF环境配置
    Java程序设置为开机自启动
    IfcArbitraryProfileDefWithVoids
    定位日志
    blazor相关资料
    老人与海 电影
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9124346.html
Copyright © 2011-2022 走看看