[USACO14FEB]路障Roadblock

题目描述

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

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。

【解题思路】

最短路

【code】

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #define M 15000
 5 #include<queue> 
 6 #define N 110
 7 using namespace std;
 8 int n,m;
 9 int po,ans;
10 int head[N],to[M],next[M],len[M],e=1;
11 void buid(int u,int v,int l)
12 {
13     next[++e]=head[u],head[u]=e;
14     to[e]=v,len[e]=l;
15 }
16 int dis[N],init[N];
17 int pre[N],fr[N],that[M],nu;
18 queue<int> q;
19 void spfa(int s)
20 {
21     memset(dis,20,sizeof(dis));
22     dis[s]=0;init[s]=1,q.push(s);
23     while(!q.empty())
24     {
25         int now=q.front();q.pop();init[now]=0;
26         for(int i=head[now];i;i=next[i])
27         {
28             int j=to[i];
29             if(dis[j]>dis[now]+len[i])
30             {
31                 dis[j]=dis[now]+len[i];
32                 pre[j]=i;fr[j]=now;
33                 if(!init[j])
34                 {
35                     init[j]=1;q.push(j);
36                 }
37             }
38         }
39     }
40 }
41 int main()
42 {
43     scanf("%d%d",&n,&m);
44     for(int i=1;i<=m;++i)
45     {
46         int u,v,l;
47         scanf("%d%d%d",&u,&v,&l);
48         buid(u,v,l);
49         buid(v,u,l);
50     }
51     spfa(1);po=dis[n];
52     int now=n;
53     while(now!=1)
54     {
55         that[++nu]=pre[now];//记路径
56         now=fr[now];
57     }
58     for(int i=1;i<=nu;++i)//枚举路径
59     {
60         len[that[i]]*=2;
61         len[that[i]^1]*=2;
62         spfa(1);//操♂作
63         ans=max(ans,dis[n]);
64         len[that[i]]/=2;
65         len[that[i]^1]/=2;
66     }
67     cout<<ans-po<<endl;//end
68     return 0;
69 } 

猜你喜欢

转载自www.cnblogs.com/66dzb/p/11565472.html