其他分享
首页 > 其他分享> > P1462 通往奥格瑞玛的道路

P1462 通往奥格瑞玛的道路

作者:互联网

原题链接

考察:最短路+二分

思路:

        二分最多的一次收取的费用的最小值,对于每一个二分值跑一遍最短路,最后判断n点是否可达即可.这里的check函数的思路类似二分经典题:搬石头

        long long数组的极大值可以初始化为memset(数组,63,size)

 1 #include <iostream>
 2 #include <cstring>
 3 #include <queue>
 4 using namespace std;
 5 typedef long long LL;
 6 typedef pair<LL,int> PLI;
 7 const int N = 10010,M = 50010,INF = 1000000010;
 8 int n,m,b,idx,h[N],w[N];
 9 LL dist[N];
10 bool st[N];
11 struct Road{
12     int to,ne,w;
13 }road[M<<1];
14 void add(int a,int b,int w)
15 {
16     road[idx].to = b,road[idx].w = w,road[idx].ne = h[a],h[a] = idx++;
17 }
18 bool check(int mid)
19 {
20     priority_queue<PLI,vector<PLI>,greater<PLI> > q;
21     memset(dist,63,sizeof dist);
22     memset(st,0,sizeof st);
23     LL t = dist[1];
24     dist[1] = 0;
25     q.push({0,1});
26     while(q.size())
27     {
28         PLI it = q.top();
29         q.pop();
30         int u = it.second;
31         if(st[u]) continue;
32         st[u] = 1;
33         for(int i=h[u];~i;i=road[i].ne)
34         {
35             int v = road[i].to;
36             if(w[v]<=mid&&dist[v]>dist[u]+road[i].w)
37             {
38                 dist[v] = dist[u]+road[i].w;
39                 q.push({dist[v],v});
40             }
41         }
42     }
43     if(st[n]&&dist[n]<=b) return 1;
44     return 0;
45 }
46 int main()
47 {
48     scanf("%d%d%d",&n,&m,&b);
49     memset(h,-1,sizeof h);
50     int maxn = 0;
51     for(int i=1;i<=n;i++) scanf("%d",&w[i]),maxn = max(maxn,w[i]);
52     while(m--)
53     {
54         int a,b,c; scanf("%d%d%d",&a,&b,&c);
55         add(a,b,c); add(b,a,c);
56     }
57     int l = 0,r = maxn+10;
58     while(l<r)
59     {
60         int mid = (1ll*l+r)>>1;
61         if(check(mid)) r = mid;
62         else l = mid+1;
63     }
64     if(r<=maxn) printf("%lld\n",r);
65     else puts("AFK");
66     return 0;
67 }

 

标签:瑞玛,dist,int,P1462,st,奥格,long,include,road
来源: https://www.cnblogs.com/newblg/p/14724018.html