洛谷P1462通往奥格瑞玛的道路——二分答案最短路
题目:https://www.luogu.org/problemnew/show/P1462
最大值最小问题,二分答案。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; int const MAXN=1e5+5; queue<int>q; int n,m,b,cost[MAXN],head[MAXN],ans,ct,l,r,dis[MAXN]; bool vis[MAXN]; struct N{ int to,next,w; N(int t=0,int n=0,int w=0):to(t),next(n),w(w) {} }edge[MAXN*10]; void add(int x,int y,int z) { edge[++ct]=N(y,head[x],z);head[x]=ct; edge[++ct]=N(x,head[y],z);head[y]=ct; } bool spfa(int mid) { memset(dis,0x3f,sizeof dis); dis[1]=0;vis[1]=1;q.push(1); while(q.size()) { int x=q.front();vis[x]=0;q.pop(); for(int i=head[x],u;i;i=edge[i].next) { if(cost[u=edge[i].to]>mid)continue; if(dis[u]>dis[x]+edge[i].w) { dis[u]=dis[x]+edge[i].w; if(!vis[u])vis[u]=1,q.push(u); } } } return dis[n]<=b; } int main() { scanf("%d%d%d",&n,&m,&b); for(int i=1;i<=n;i++) scanf("%d",&cost[i]),r=max(r,cost[i]); for(int i=1,x,y,z;i<=m;i++) { scanf("%d%d%d",&x,&y,&z); add(x,y,z); } ans=-1; while(l<=r) { int mid=((l+r)>>1); if(spfa(mid))ans=mid,r=mid-1; else l=mid+1; } if(ans==-1)printf("AFK"); else printf("%d",ans); return 0; }