Luogu P1951 收费站_NOI导刊2009提高(2) 二分 最短路

思路:二分+最短路

提交:1次

题解:

二分最后的答案。

$ck()$: 对于每次的答案$md$跑$s,t$的最短路,但是不让$c[u]>md$的点去松弛别的边,即保证最短路不经过这个点。最后$return\space dis(s,t)<=$油箱容量

代码:

#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
#define R register int
using namespace std;
//你弱,有什么资格休息
#define ull unsigned long long
#define ll long long
#define pause (for(R i=1;i<=10000000000;++i))
#define In freopen("NOIPAK++.in","r",stdin)
#define Out freopen("out.out","w",stdout)
namespace Fread {
static char B[1<<15],*S=B,*D=B;
#ifndef JACK
#define getchar() (S==D&&(D=(S=B)+fread(B,1,1<<15,stdin),S==D)?EOF:*S++)
#endif
inline int g() {
    R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix;
    if(ch==EOF) return EOF; do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
} inline bool isempty(const char& ch) {return (ch<=36||ch>=127);}
inline void gs(char* s) {
    register char ch; while(isempty(ch=getchar()));
    do *s++=ch; while(!isempty(ch=getchar()));
}
} using Fread::g; using Fread::gs;
namespace Luitaryi {
#define pii pair<ll,int>
#define mp make_pair
const int N=1e+4+10,M=1e+5+10;
int n,m,s,t,W,mx,cnt;
int vr[M],nxt[M],w[M],fir[N],c[N];
ll d[N]; bool vis[N];
inline void add(int u,int v,int ww) {vr[++cnt]=v,nxt[cnt]=fir[u],w[cnt]=ww,fir[u]=cnt;}
priority_queue<pii > q;
inline bool ck(int x) { q.push(mp(0,s)); if(c[s]>x) return false;
    memset(d,0x3f,sizeof(d)),memset(vis,0,sizeof(vis)); d[s]=0;
    while(q.size()) { R u=q.top().second; q.pop();
        if(vis[u]) continue; vis[u]=true;
        if(c[u]>x) continue;
        for(R i=fir[u];i;i=nxt[i]) { R v=vr[i];
            if(d[v]>d[u]+w[i]) {
                d[v]=d[u]+w[i]; q.push(mp(-d[v],v));
            }
        }
    } return d[t]<=W;
}
inline void main() {
    n=g(),m=g(),s=g(),t=g(),W=g();
    for(R i=1;i<=n;++i)    c[i]=g(),mx=max(c[i],mx);
    for(R i=1,u,v,w;i<=m;++i) u=g(),v=g(),w=g(),add(u,v,w),add(v,u,w);
    R l=max(c[s],c[t]),r=mx+1; while(l<r) {
        R md=l+r>>1; if(ck(md)) r=md; else l=md+1;
    } printf("%d\n",l==mx+1?-1:l);
}
}
signed main() {
    Luitaryi::main(); return 0;
}

2019.07.15

posted @ 2019-07-15 00:02  LuitaryiJack  阅读(200)  评论(2编辑  收藏  举报