Luogu P1462 通往奥格瑞玛的道路 二分答案+最短路

先二分答案,再跑最短路,跑的时候遇到 过路费超过二分的答案的 就不拿他更新最短路

#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

 

posted @ 2019-04-14 21:34  LuitaryiJack  阅读(106)  评论(0编辑  收藏  举报