[luogu1462] 通往奥格瑞玛的道路
Posted Neworld2002
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[luogu1462] 通往奥格瑞玛的道路相关的知识,希望对你有一定的参考价值。
首先就发现了这题可以二分答案,毕竟是求最大的最小。
考虑二分最大边,则所有边权大于二分值的边都不能选。
在此基础上跑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] 通往奥格瑞玛的道路的主要内容,如果未能解决你的问题,请参考以下文章
luogu1462通往奥格瑞玛的道路 (最短路)(spfa)