先二分答案,再跑最短路,跑的时候遇到 过路费超过二分的答案的 就不拿他更新最短路
#include<cstdio> #include<iostream> #include<cstring> #include<queue> #define R register int using namespace std; inline int g() { R ret=0; register char ch; while(!isdigit(ch=getchar())) ; do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret; } int n,m,B,l,r,cnt; int vr[100010],nxt[100010],fir[10010],c[10010]; long long w[100010],d[10010]; bool vis[10010]; queue<int>q; inline void add(int u,int v,int ww) {vr[++cnt]=v,w[cnt]=ww,nxt[cnt]=fir[u],fir[u]=cnt;} inline bool spafa(int k) { memset(d,0x3f,sizeof(d)); memset(vis,0,sizeof(vis)); if(k<c[1]) return false; d[1]=0; q.push(1),vis[1]=true; while(q.size()) { R u=q.front(); q.pop(); vis[u]=false; for(R i=fir[u];i;i=nxt[i]) { R v=vr[i]; if(c[v]>k) continue; if(d[v]>d[u]+w[i]) { d[v]=d[u]+w[i]; if(!vis[v]) q.push(v),vis[v]=true; } } } return d[n]<=B; } signed main() { n=g(),m=g(),B=g(); for(R i=1;i<=n;++i) c[i]=g(),r=max(r,c[i]); l=max(c[1],c[n]); for(R i=1,u,v,w;i<=m;++i) { u=g(),v=g(),w=g(); if(u!=v) add(u,v,w),add(v,u,w); } if(!spafa(r)) {printf("AFK"); putchar('\n'); return 0; } while(l<r){ R md=(l+r)>>1; if(spafa(md)) r=md; else l=md+1; } printf("%d",l),putchar('\n'); }
2019.04.14