• CODEVS——T1519 过路费


     空间限制: 256000 KB
     题目等级 : 大师 Master
     
     
    题目描述 Description

        在某个遥远的国家里,有 n个城市。编号为 1,2,3,…,n。这个国家的政府修建了m 条双向道路,每条道路连接着两个城市。政府规定从城市 S 到城市T需要收取的过路费为所经过城市之间道路长度的最大值。如:A到B长度为 2,B到C 长度为3,那么开车从 A经过 B到C 需要上交的过路费为 3。
        佳佳是个做生意的人,需要经常开车从任意一个城市到另外一个城市,因此他需要频繁地上交过路费,由于忙于做生意,所以他无时间来寻找交过路费最低的行驶路线。然而, 当他交的过路费越多他的心情就变得越糟糕。 作为秘书的你,需要每次根据老板的起止城市,提供给他从开始城市到达目的城市,最少需要上交多少过路费。

    输入描述 Input Description

        第一行是两个整数 n 和m,分别表示城市的个数以及道路的条数。 
        接下来 m 行,每行包含三个整数 a,b,w(1≤a,b≤n,0≤w≤10^9),表示a与b之间有一条长度为 w的道路。
        接着有一行为一个整数 q,表示佳佳发出的询问个数。 
        再接下来 q行,每一行包含两个整数 S,T(1≤S,T≤n,S≠T), 表示开始城市S 和目的城市T。

    输出描述 Output Description

        输出共q行,每行一个整数,分别表示每个询问需要上交的最少过路费用。输入数据保证所有的城市都是连通的。

    样例输入 Sample Input

    4 5 
    1 2 10 
    1 3 20 
    1 4 100 
    2 4 30 
    3 4 10 

    1 4 
    4 1

    样例输出 Sample Output

    20 
    20

    数据范围及提示 Data Size & Hint

    对于 30%的数据,满足 1≤ n≤1000,1≤m≤10000,1≤q≤100; 
    对于 50%的数据,满足 1≤ n≤10000,1≤m≤10000,1≤q≤10000; 
    对于 100%的数据,满足 1≤ n≤10000,1≤m≤100000,1≤q≤10000;

    (和货车运输很像)

    先求出最小生成树(使图简化),在此树上做倍增,维护最大代价

     1 #include <algorithm>
     2 #include <cstring>
     3 #include <cstdio>
     4 
     5 using namespace std;
     6 
     7 const int N(10000+15);
     8 const int M(100000+5);
     9 int n,m,q,u,v,ans;
    10 struct Edge
    11 {
    12     int u,v,w;
    13 }road[M];
    14 bool cmp(Edge a,Edge b)
    15 {
    16     return a.w<b.w;
    17 }
    18 
    19 int head[N],sumedge;
    20 struct E
    21 {
    22     int v,next,w;
    23     E(int v=0,int next=0,int w=0):
    24         v(v),next(next),w(w){}
    25 }edge[N<<1];
    26 void ins(int u,int v,int w)
    27 {
    28     edge[++sumedge]=E(v,head[u],w);
    29     head[u]=sumedge;
    30 }
    31 
    32 int fa[N];
    33 int find(int x)
    34 {
    35     return x==fa[x]?x:fa[x]=find(fa[x]);
    36 }
    37 void K()
    38 {
    39     int cnt=0;
    40     sort(road+1,road+m+1,cmp);
    41     for(int i=1;i<=n;i++) fa[i]=i;
    42     for(int i=1;i<=m;i++)
    43     {
    44         int x=road[i].u,y=road[i].v;
    45         int fx=find(x),fy=find(y);
    46         if(fx==fy) continue;
    47         fa[fx]=fy;
    48         ins(x,y,road[i].w);
    49         ins(y,x,road[i].w);
    50         if(++cnt==n-1) return ;
    51     }
    52 }
    53 
    54 int dad[N],val[N],deep[N];
    55 void DFS(int x)
    56 {
    57     deep[x]=deep[dad[x]]+1;
    58     for(int i=head[x];i;i=edge[i].next)
    59     {
    60         int v=edge[i].v;
    61         if(dad[v]) continue;
    62         val[v]=edge[i].w;
    63         dad[v]=x;  DFS(v);
    64     }
    65 }
    66 int LCA(int x,int y)
    67 {
    68     int maxx=0,maxn=0;
    69     if(deep[x]>deep[y]) swap(x,y);
    70     for(;deep[y]>deep[x];y=dad[y]) maxx=max(maxx,val[y]);
    71     for(;x!=y;x=dad[x],y=dad[y]) maxn=max(maxn,max(val[x],val[y]));
    72     return max(maxn,maxx);
    73 }
    74 
    75 int main()
    76 {
    77     scanf("%d%d",&n,&m);
    78     for(int i=1;i<=m;i++)
    79         scanf("%d%d%d",&road[i].u,&road[i].v,&road[i].w);
    80     K(); DFS(1);
    81     scanf("%d",&q);
    82     for(;q--;)
    83     {
    84         scanf("%d%d",&u,&v);
    85         printf("%d
    ",LCA(u,v));
    86     }
    87     return 0;
    88 }
    ——每当你想要放弃的时候,就想想是为了什么才一路坚持到现在。
  • 相关阅读:
    小进步一点
    首个vue.js项目收尾中……
    elememtui(有关权限的那些事)
    vue.js2.0+elementui ——> 后台管理系统
    console.log篇
    select下拉框不能赋值
    vue中的小踩坑(01)
    vue2.0+element-ui(01简单点的单页面)
    lodash(二)对象+循环遍历+排序
    lodash(一)数组
  • 原文地址:https://www.cnblogs.com/Shy-key/p/7308057.html
Copyright © 2020-2023  润新知