luogu P1462 通往奥格瑞玛的道路
这道题的题面相当的迷,我看了半天都没懂。最后看了题解的解释才懂。
他是这么个意思:对于所有能活着走到终点的路径,输出每一条路径中过路费最多的城市的最小值。
那么自然想到二分过路费,然后用dijkstra或spfa判断是否存在一条路径,该路径上的每一个城市的过路费都小于当前二分值mid。用dijkstra复杂度就是O(nlog2n),spfa玄学,但也能过。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #include<cstdlib> 7 #include<cctype> 8 #include<vector> 9 #include<stack> 10 #include<queue> 11 using namespace std; 12 #define enter puts("") 13 #define space putchar(' ') 14 #define Mem(a, x) memset(a, x, sizeof(a)) 15 #define rg register 16 typedef long long ll; 17 typedef double db; 18 const int INF = 0x3f3f3f3f; 19 const db eps = 1e-8; 20 const int maxn = 1e4 + 5; 21 const int maxe = 5e4 + 5; 22 inline ll read() 23 { 24 ll ans = 0; 25 char ch = getchar(), last = ' '; 26 while(!isdigit(ch)) last = ch, ch = getchar(); 27 while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar(); 28 if(last == '-') ans = -ans; 29 return ans; 30 } 31 inline void write(ll x) 32 { 33 if(x < 0) x = -x, putchar('-'); 34 if(x >= 10) write(x / 10); 35 putchar(x % 10 + '0'); 36 } 37 38 int n, m; 39 ll b, a[maxn], Max = 0; 40 41 struct Edge 42 { 43 int nxt, to; ll w; 44 }e[maxe << 1]; 45 int head[maxn], ecnt = -1; 46 void addEdge(int x, int y, ll w) 47 { 48 e[++ecnt] = (Edge){head[x], y, w}; 49 head[x] = ecnt; 50 } 51 52 #define pr pair<ll, int> 53 #define mp make_pair 54 ll dis[maxn]; 55 bool in[maxn]; 56 priority_queue<pr, vector<pr>, greater<pr> > q; 57 bool dijkstra(ll x) 58 { 59 for(int i = 1; i <= n; ++i) dis[i] = (ll)INF * (ll)INF, in[i] = 0; 60 dis[1] = 0; 61 while(!q.empty()) q.pop(); 62 q.push(mp(dis[1], 1)); 63 while(!q.empty()) 64 { 65 int now = q.top().second; q.pop(); 66 if(in[now]) continue; 67 in[now] = 1; 68 for(int i = head[now]; i != -1; i = e[i].nxt) 69 { 70 if(dis[e[i].to] > dis[now] + e[i].w && dis[now] + e[i].w < b && a[e[i].to] <= x) 71 { 72 if(e[i].to == n) return 1; 73 dis[e[i].to] = dis[now] + e[i].w; 74 q.push(mp(dis[e[i].to], e[i].to)); 75 } 76 } 77 } 78 return 0; 79 } 80 81 int main() 82 { 83 Mem(head, -1); 84 n = read(); m = read(); b = read(); 85 for(int i = 1; i <= n; ++i) a[i] = read(); 86 for(int i = 1; i <= m; ++i) 87 { 88 int x = read(), y = read(); ll w = read(); 89 if(w > b) continue; 90 Max = max(Max, w); 91 addEdge(x, y, w); addEdge(y, x, w); 92 } 93 ll L = 0, R = (ll)INF * (ll)INF; 94 while(L < R) 95 { 96 ll mid = (L + R) >> 1; 97 if(dijkstra(mid)) R = mid; 98 else L = mid + 1; 99 } 100 if(L == (ll)INF * (ll)INF) puts("AFK"); 101 else write(L), enter; 102 return 0; 103 }