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