Luogu P1462 && P1951

首先有两个最短路,可以考虑把一个东西拿出来二分,也就是可以二分最小值,但是注意不要用SPFA他死了,可以用Dij跑最短路,再二分,效率会大大提高

1.SPFA

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+5;
const int M=1e5+5;
int n,m,tot,head[M];
long long f[N],d[N],b,a[N];
bool vis[N];
struct node{int to,next;long long val;}e[M];
void add(int u,int v,int w){e[++tot].to=v;e[tot].next=head[u];e[tot].val=w;head[u]=tot;}
bool spfa(long long k){
    queue<int> q;
    if(a[1]>k||a[n]>k)return false;
    memset(vis,0,sizeof(vis));
    for(int i=2;i<=n;i++)d[i]=LLONG_MAX;
    d[1]=0;q.push(1);vis[1]=1;
    while(!q.empty()){
        int u=q.front();q.pop();vis[u]=0;
        for(int i=head[u];i;i=e[i].next){
            int v=e[i].to,z=e[i].val;
            if(a[v]>k)continue;
            if(d[v]>d[u]+z){
                d[v]=d[u]+z;
                if(!vis[v])q.push(v),vis[v]=1;
            }
        }
    }
    return d[n]<=b;
}
int main(){
    //freopen("a.in","r",stdin);
    long long c;
    scanf("%d%d%lld",&n,&m,&b);
    for(int i=1;i<=n;i++)
     scanf("%lld",&f[i]),a[i]=f[i];
    for(int i=1,u,v;i<=m;i++){
        scanf("%d%d%lld",&u,&v,&c);
        add(u,v,c);add(v,u,c);
    }
    sort(f+1,f+n+1);
    int l=0,r=n,best=-1;
    while(l<r){
        int mid=(l+r)>>1;
        if(spfa(f[mid]))
         best=mid,r=mid-1;
        else
         l=mid+1;
    }
    if(spfa(f[l]))best=l;
    if(best<0)puts("AFK");
    else printf("%lld\n",f[best]);
}

2.DIJ

#include<bits/stdc++.h>
#pragma GCC optimize("O2")
#pragma GCC optimize("O3")
using namespace std;
const int N=1e4+5;
const int M=1e5+5;
int n,m,tot,head[M],st,ed;
int f[N],d[N],b,a[N];
bool vis[N];
struct node{int to,next,val;}e[M];
priority_queue<pair<int,int> > q;
void add(int u,int v,int w){e[++tot].to=v;e[tot].next=head[u];e[tot].val=w;head[u]=tot;}
bool spfa(int k){
    if(a[st]>k||a[ed]>k)return false;
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++)d[i]=INT_MAX;
    d[st]=0;q.push(make_pair(0,st));;
    while(!q.empty()){
        int u=q.top().second;q.pop();
        if(vis[u])continue;
        vis[u]=1;
        for(int i=head[u];i;i=e[i].next){
            int v=e[i].to,z=e[i].val;
            if(a[v]>k)continue;
            if(d[v]>d[u]+z){
                d[v]=d[u]+z;
                q.push(make_pair(-d[v],v));
            }
        }
    }
    return d[ed]<=b;
}
int main(){
    scanf("%d%d%d%d%d",&n,&m,&st,&ed,&b);
    for(int i=1;i<=n;i++)
     scanf("%d",&f[i]),a[i]=f[i];
    for(int i=1,u,v,c;i<=m;i++){
        scanf("%d%d%d",&u,&v,&c);
        add(u,v,c);add(v,u,c);
    }
    sort(f+1,f+n+1);
    int l=1,r=n,best=-1;
    while(l<r){
        int mid=(l+r)>>1;
        if(spfa(f[mid]))
         best=mid,r=mid-1;
        else
         l=mid+1;
    }
    if(spfa(f[l]))best=l;
    if(best<0)puts("-1");
    else printf("%d\n",f[best]);
}

猜你喜欢

转载自www.cnblogs.com/coder-cjh/p/11336255.html