1379 Toll Management (两次最短路)

题意

要求有向图上一点到另一点的长度不超过p的最短路上的最长的边最长是多少。

分析

不能单纯的跑一边或者两边最短路,可能最短路的情况下边不是最大的。

反向建立图,由终点和起点做两次最短路,然后枚举每一条边,找出最长的边,且加上这条边后,由起点到终点的长度不大于p。

这里最短路可以用各种方法,不想写优先队列。用了bellman-ford

代码

 1 #define rep(x,y,z) for(int x=y;x<z;x++)
 2 #define drep(x,y,z) for(int x=y;x>=z;x--)
 3 #define pb(x) push_back(x)
 4 #define mp(x,y) make_pair(x,y)
 5 #define clr(x,y) memset(x,y,sizeof(x))
 6 #define fi first
 7 #define se second
 8 
 9 #include <iostream>
10 #include <stdio.h>
11 #include <string.h>
12 #include <algorithm>
13 #include <vector>
14 #include <queue>
15 using namespace std;
16 
17 const int N = 1e4 + 10;
18 const int inf = 0x3f3f3f3f;
19 
20 vector<pair<pair<int,int>,int> > edge[2];
21 int dis[2][N];
22 
23 void init(){
24     clr(dis,inf);
25     edge[0].clear();
26     edge[1].clear();
27 }
28 
29 void slove(int k , int s){
30     int size = edge[k].size();
31     dis[k][s] = 0;
32     while(1){
33         bool ok = 0;
34         rep(i,0,size){
35             int f = edge[k][i].fi.fi;
36             int r = edge[k][i].fi.se;
37             int w = edge[k][i].se;
38             //
39             if(dis[k][f] + w < dis[k][r]){
40                 dis[k][r] = dis[k][f] + w;
41                 ok = 1;
42             }
43             //
44         }
45         if(!ok) break;
46     }
47 }
48 
49 void read(int m){
50     rep(i,0,m){
51         int u , v , w;
52         scanf("%d %d %d",&u,&v,&w);
53         edge[0].pb(mp(mp(u,v),w));
54         edge[1].pb(mp(mp(v,u),w));
55     }
56 }
57 
58 int main(){
59     int t;
60     scanf("%d",&t);
61     rep(tt,1,t+1){
62         int n , m , s , t , p;
63         scanf("%d %d %d %d %d",&n,&m,&s,&t,&p);
64         init();
65         read(m);
66         slove(0,s);
67         slove(1,t);
68         int size = edge[0].size();
69         int ans = -1;
70         rep(i,0,size){
71             int a = edge[0][i].fi.fi;
72             int b = edge[0][i].fi.se;
73             int w = edge[0][i].se;
74             //
75             if(dis[0][a] + dis[1][b] + w <= p) ans = max(ans,w);
76             //if(dis[1][a] + dis[0][b] + w <= p) ans = max(ans,w);
77             //
78         }
79         printf("Case %d: %d
",tt,ans);
80     }
81     return 0;
82 }
原文地址:https://www.cnblogs.com/ticsmtc/p/6115333.html