[洛谷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 }

 

posted @ 2019-01-25 12:16  AC-Evil  阅读(159)  评论(0编辑  收藏  举报