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

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


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


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

    【题解】

    首先取图的最大生成树建成一棵树,然后问题就转化为了求两点到lca路径上的最小边权,用倍增处理。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<ctime>
     6 #include<cmath>
     7 #include<algorithm>
     8 using namespace std;
     9 #define INF 1000000000
    10 #define MAXM 50010
    11 #define MAXN 10010
    12 struct node{int x,y,v;}E[MAXM];
    13 struct node2{int y,next,v;}e[MAXN*2];
    14 int n,m,q,len,vis[MAXN],f[MAXN],Link[MAXN],deep[MAXN],anc[MAXN][25],w[MAXN][25];
    15 inline int read()
    16 {
    17     int x=0,f=1;  char ch=getchar();
    18     while(!isdigit(ch))  {if(ch=='-')  f=-1;  ch=getchar();}
    19     while(isdigit(ch))  {x=x*10+ch-'0';  ch=getchar();}
    20     return x*f;
    21 }
    22 bool cmp(node a,node b) {return a.v>b.v;} 
    23 int find(int x)  {return f[x]==x?x:f[x]=find(f[x]);}
    24 void insert(int x,int y,int v) {e[++len].next=Link[x];Link[x]=len;e[len].y=y;e[len].v=v;}
    25 void dfs(int x)
    26 {
    27     vis[x]=1;
    28     for(int i=1;i<=20;i++)  {anc[x][i]=anc[anc[x][i-1]][i-1]; w[x][i]=min(w[x][i-1],w[anc[x][i-1]][i-1]);}
    29     for(int i=Link[x];i;i=e[i].next)
    30         if(!vis[e[i].y])
    31         {
    32             deep[e[i].y]=deep[x]+1;
    33             anc[e[i].y][0]=x;
    34             w[e[i].y][0]=e[i].v;
    35             dfs(e[i].y);
    36         }
    37 }
    38 int lca(int x,int y)
    39 {
    40     if(deep[x]<deep[y])  swap(x,y);
    41     for(int i=20;i>=0;i--)  if(deep[anc[x][i]]>=deep[y])  x=anc[x][i];
    42     if(x==y)  return x;
    43     for(int i=20;i>=0;i--)  if(anc[x][i]!=anc[y][i])  x=anc[x][i],y=anc[y][i];
    44     return anc[x][0];
    45 }
    46 int ask(int x,int f)
    47 {
    48     int mn=INF;
    49     int t=deep[x]-deep[f];
    50     for(int i=0;i<=16;i++)if(t&(1<<i)){mn=min(mn,w[x][i]);x=anc[x][i];}
    51     return mn;
    52 }
    53 int main()
    54 {
    55     freopen("truck.in","r",stdin);
    56     freopen("truck.out","w",stdout);
    57     memset(w,127/3,sizeof(w));
    58     n=read();  m=read();
    59     for(int i=1;i<=m;i++)  {E[i].x=read();  E[i].y=read();  E[i].v=read();}
    60     sort(E+1,E+m+1,cmp);
    61     for(int i=1;i<=n;i++)  f[i]=i;
    62     for(int i=1;i<=m;i++)
    63     {
    64         int x=find(E[i].x),y=find(E[i].y);
    65         if(x!=y)
    66         {
    67             f[x]=y;
    68             insert(E[i].x,E[i].y,E[i].v);
    69             insert(E[i].y,E[i].x,E[i].v);
    70         }
    71     }
    72     for(int i=1;i<=n;i++)  if(!vis[i])  dfs(i);
    73     q=read();
    74     for(int i=1;i<=q;i++)
    75     {
    76         int x=read(),y=read();
    77         if(find(x)!=find(y))  {printf("-1
    ");  continue;}
    78         int t=lca(x,y);
    79         printf("%d
    ",min(ask(x,t),ask(y,t)));
    80     }
    81     return 0;
    82 }
  • 相关阅读:
    sql2slack alash3al 开源的又个轻量级工具
    pgspider fetchq 扩展docker镜像
    godns 集成coredns 的demo
    godns 简单dnsmasq 的dns 替换方案
    aviary.sh 一个基于bash的分布式配置管理工具
    使用coredns 的template plugin实现一个xip 服务
    nginx 代理 coredns dns 服务
    基于nginx proxy dns server
    几个不错的geodns server
    spring boot rest api 最好添加servlet.context-path
  • 原文地址:https://www.cnblogs.com/chty/p/5975138.html
Copyright © 2011-2022 走看看