[洛谷P1462]通往奥格瑞玛的道路
原题传送门
这道题是要求点$1$到$n$路径长度在$b$以内,所经过点的$f_i$最大值最小。所以我们采用二分答案,把点删掉判断是否有最短路在$b$以内。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <queue> 6 7 using namespace std; 8 9 #define re register 10 #define rep(i, a, b) for (re int i = a; i <= b; ++i) 11 #define repd(i, a, b) for (re int i = a; i >= b; --i) 12 #define maxx(a, b) a = max(a, b); 13 #define minn(a, b) a = min(a, b); 14 #define LL long long 15 #define inf (1 << 30) 16 17 inline int read() { 18 int w = 0, f = 1; char c = getchar(); 19 while (!isdigit(c)) f = c == '-' ? -1 : f, c = getchar(); 20 while (isdigit(c)) w = (w << 3) + (w << 1) + (c ^ '0'), c = getchar(); 21 return w * f; 22 } 23 24 const int maxn = 1e4 + 5, maxm = 5e4 + 5; 25 26 struct Edge { 27 int u, v, w, pre; 28 }; 29 30 struct Node { 31 int u, d; 32 bool operator < (const Node &rhs) const { 33 return d > rhs.d; 34 } 35 }; 36 37 priority_queue<Node> Q, empty; 38 39 int n, m, b; 40 41 struct Tf { 42 int n, w; 43 bool operator < (const Tf &rhs) const { 44 return w > rhs.w; 45 } 46 } f[maxn]; 47 48 struct Graph { 49 Edge edges[maxm << 1]; 50 int m, n, G[maxn]; 51 int vis[maxn], dis[maxn]; 52 void init(int n) { 53 this->n = n; 54 m = 0; 55 memset(G, 0, sizeof(G)); 56 } 57 void AddEdge(int u, int v, int w) { 58 edges[++m] = (Edge){u, v, w, G[u]}; 59 G[u] = m; 60 } 61 void dijkstra(int x) { 62 memset(dis, 0x3f, sizeof(dis)); 63 memset(vis, 0, sizeof(vis)); 64 dis[1] = 0; 65 rep(i, 1, x) vis[f[i].n] = 1; 66 Q = empty; 67 Q.push((Node){1, 0}); 68 while (!Q.empty()) { 69 int u = Q.top().u; Q.pop(); 70 if (vis[u]) continue; 71 vis[u] = 1; 72 for (int i = G[u]; i; i = edges[i].pre) { 73 Edge &e = edges[i]; 74 if (!vis[e.v] && dis[u] + e.w < dis[e.v]) { 75 dis[e.v] = dis[u] + e.w; 76 Q.push((Node){e.v, dis[e.v]}); 77 } 78 } 79 } 80 } 81 } G; 82 83 int main() { 84 n = read(), m = read(), b = read(); 85 G.init(n); 86 87 rep(i, 1, n) f[i] = (Tf){i, read()}; 88 89 rep(i, 1, m) { 90 int u = read(), v = read(), w = read(); 91 G.AddEdge(u, v, w); 92 G.AddEdge(v, u, w); 93 } 94 95 sort(f+1, f+n+1); 96 97 int l = 0, r = n, ans = -1; 98 while (l <= r) { 99 int mid = (l + r) >> 1; 100 G.dijkstra(mid); 101 if (G.dis[n] > b) r = mid-1; 102 else l = mid+1, ans = mid; 103 } 104 105 if (ans == -1) printf("AFK"); 106 else printf("%d", f[ans+1].w); 107 108 return 0; 109 }