[luogu1462] 通往奧格瑞瑪的道路
阿新 • • 發佈:2018-09-15
distance www. cstring ont 最小 pri check problem code
傳送門
首先就發現了這題可以二分答案,畢竟是求最大的最小。
考慮二分最大邊,則所有邊權大於二分值的邊都不能選。
在此基礎上跑SPFA,求出從1到N耗的最少血量。然後觀察血量是否為空即可。
#include <cstdio> #include <cstring> #include <algorithm> #define SIZE 16383 #define MAXN 10005 #define MAXM 50005 int head[MAXN]; struct edge{ int v,w,next; }G[MAXM<<1]; int value[MAXN]; int dis[MAXN]; int vis[MAXN]; int N,M,B; int tot = 0; inline void add(int u,int v,int w){ G[++tot].v = v;G[tot].w = w;G[tot].next = head[u];head[u] = tot; } struct queue{ int q[MAXN];int head,tail; inline void reset(){head = 1,tail = 0;} inline void push(int x){ q[(++tail)&SIZE] = x; } inline void pop(){ ++head; } inline int front(){ return q[head&SIZE]; } inline bool empty(){ return head>tail; } }q; inline void SPFA(int distance){ for(register int i=1;i<=N;++i){ dis[i] = vis[i] = 0; } q.reset(); dis[1] = B; vis[1] = 1; q.push(1); if(value[1]>distance)return; while(!q.empty()){ int u = q.front();q.pop(); for(register int i=head[u];i;i=G[i].next){ int v = G[i].v; if(value[v]>distance)continue; if(dis[u]-G[i].w>dis[v]){ dis[v] = dis[u] - G[i].w; if(!vis[v]){ vis[v] = 1; q.push(v); } } } vis[u] = 0; } } inline bool Check(int distance){ SPFA(distance); return dis[N]>0; } int main(){ scanf("%d%d%d",&N,&M,&B); for(register int i=1;i<=N;++i){ scanf("%d",&value[i]); } int u,v,w; for(register int i=1;i<=M;++i){ scanf("%d%d%d",&u,&v,&w); add(u,v,w);add(v,u,w); } int l = 0;int r = 1000000000; while(l<r){ int mid = (l+r)>>1; if(Check(mid))r = mid; else l = mid+1; } if(!Check(l))puts("AFK"); else printf("%d",l); return 0; }
[luogu1462] 通往奧格瑞瑪的道路