luogu P1462 通往奥格瑞玛的道路

嘟嘟嘟

 

这道题的题面相当的迷,我看了半天都没懂。最后看了题解的解释才懂。

他是这么个意思:对于所有能活着走到终点的路径,输出每一条路径中过路费最多的城市的最小值。

 

那么自然想到二分过路费,然后用dijkstra或spfa判断是否存在一条路径,该路径上的每一个城市的过路费都小于当前二分值mid。用dijkstra复杂度就是O(nlog2n),spfa玄学,但也能过。

  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 }
View Code

 

posted @ 2018-10-30 15:48  mrclr  阅读(138)  评论(0编辑  收藏  举报