zoukankan      html  css  js  c++  java
  • 洛谷—— P2176 [USACO14FEB]路障Roadblock

    https://www.luogu.org/problem/show?pid=2176

    题目描述

    每天早晨,FJ从家中穿过农场走到牛棚。农场由 N 块农田组成,农田通过 M 条双向道路连接,每条路有一定长度。FJ 的房子在 1 号田,牛棚在 N 号田。没有两块田被多条道路连接,以适当的路径顺序总是能在农场任意一对田间行走。当FZ从一块田走到另一块时,总是以总路长最短的道路顺序来走。

    FJ 的牛呢,总是不安好心,决定干扰他每天早晨的计划。它们在 M 条路的某一条上安放一叠稻草堆,使这条路的长度加倍。牛希望选择一条路干扰使得FJ 从家到牛棚的路长增加最多。它们请你设计并告诉它们最大增量是多少。

    输入输出格式

    输入格式:

    第 1 行:两个整数 N, M。

    第 2 到 M+1 行:第 i+1 行包含三个整数 A_i, B_i, L_i,A_i 和 B_i 表示道路 i 连接的田的编号,L_i 表示路长。

    输出格式:

    第 1 行:一个整数,表示通过使某条路加倍而得到的最大增量。

    输入输出样例

    输入样例#1:
    5 7
    2 1 5
    1 3 1
    3 2 8
    3 5 7
    3 4 3
    2 4 7
    4 5 2
    输出样例#1:
    2

    说明

    【样例说明】

    若使 3 和 4 之间的道路长加倍,最短路将由 1-3-4-5 变为 1-3-5。

    【数据规模和约定】

    对于 30%的数据,N <= 70,M <= 1,500。

    对于 100%的数据,1 <= N <= 100,1 <= M <= 5,000,1 <= L_i <= 1,000,000。

    每次加倍在最短路上的边,依次更新答案

     1 #include <cstring>
     2 #include <cstdio>
     3 #include <queue>
     4 
     5 #define max(a,b) (a>b?a:b)
     6 inline void read(int &x)
     7 {
     8     x=0; register char ch=getchar();
     9     for(;ch>'9'||ch<'0';) ch=getchar();
    10     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
    11 }
    12 const int M(5005);
    13 const int N(110);
    14 int n,m,head[N],sumedge=1;
    15 struct Edge {
    16     int v,next,w;
    17     Edge(int v=0,int next=0,int w=0):v(v),next(next),w(w){}
    18 }edge[M<<1];
    19 inline void ins(int u,int v,int w)
    20 {
    21     edge[++sumedge]=Edge(v,head[u],w); head[u]=sumedge;
    22     edge[++sumedge]=Edge(u,head[v],w); head[v]=sumedge;
    23 }
    24 
    25 bool inq[N];
    26 std::queue<int>que;
    27 int dis[N],mindis,ansdis,pre[N],zz[N];
    28 inline int SPFA(int s)
    29 {
    30     for(int i=1; i<=n; ++i)
    31         dis[i]=0x3f3f3f3f,inq[i]=0;
    32     for(; !que.empty(); ) que.pop();
    33     que.push(s); dis[s]=0;
    34     for(int u,v; !que.empty(); )
    35     {
    36         u=que.front(); que.pop(); inq[u]=0;
    37         for(int i=head[u]; i; i=edge[i].next)
    38         {
    39             v=edge[i].v;
    40             if(dis[v]>dis[u]+edge[i].w)
    41             {
    42                 zz[v]=u; dis[v]=dis[u]+edge[i].w;
    43                 if(!inq[v]) inq[v]=1,que.push(v);
    44             }
    45         } 
    46     }
    47     return dis[n];
    48 }
    49 
    50 int Presist()
    51 {
    52     read(n),read(m);
    53     for(int u,v,w,i=1; i<=m; ++i)
    54         read(u),read(v),read(w),ins(u,v,w);
    55     mindis=SPFA(1);memcpy(&pre,&zz,sizeof(zz));
    56     for(int v,u=1; u<=n; ++u)
    57         for(int i=head[u]; i; i=edge[i].next)
    58         {
    59             v=edge[i].v;
    60             if(pre[v]==u||pre[u]==v)
    61             {
    62                 edge[i].w<<=1;
    63                 edge[i^1].w<<=1;
    64                 ansdis=max(ansdis,SPFA(1)-mindis);
    65                 edge[i].w>>=1;
    66                 edge[i^1].w>>=1;
    67             }
    68         }
    69     printf("%d
    ",ansdis);
    70     return 0;
    71 }
    72 
    73 int Aptal=Presist();
    74 int main(int argc,char*argv[]){;}
    ——每当你想要放弃的时候,就想想是为了什么才一路坚持到现在。
  • 相关阅读:
    apply 和 call 方法详解【转载】
    npm无法安装node-sass的解决方法
    rem
    创建和存储 cookie
    webpack学习(一):webpack的安装和命令行
    gulp常用的插件
    移动前端开发之viewport的深入理解
    JavaSE中Collection集合框架学习笔记(3)——遍历对象的Iterator和收集对象后的排序
    JavaSE中Collection集合框架学习笔记(2)——拒绝重复内容的Set和支持队列操作的Queue
    JavaSE中Collection集合框架学习笔记(1)——具有索引的List
  • 原文地址:https://www.cnblogs.com/Shy-key/p/7602534.html
Copyright © 2011-2022 走看看