洛谷 P1462 通往奥格瑞玛的道路(最短路_SPFA)

版权声明: https://blog.csdn.net/Dawn_LLLLLLL/article/details/79947208

传送门


题目其实是求经过城市最多的一次的费用最小值
由于要满足费用与血量两个条件,我们用血量建边,二分枚举费用跑最短路。

Code:

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
using namespace std;

const int INF=1e9;

struct node{int x,y,c,next,other;}a[100010];
int n,m,k,l,r,ans,len=0;
int b[100010],first[100010],f[100010],q[100010];
bool v[100010];

void ins(int x,int y,int c){len++;a[len].x=x;a[len].y=y;a[len].c=c;a[len].next=first[x];first[x]=len;}

bool spfa(int t)
{
    memset(f,63,sizeof(f));f[1]=0;
    memset(v,false,sizeof(v));v[1]=true;
    int st=1,ed=2;q[st]=1;
    while(st!=ed)
    {
        int x=q[st];
        for(int i=first[x];i;i=a[i].next)
        {
            int y=a[i].y;
            if(f[y]>f[x]+a[i].c)
            {
                f[y]=f[x]+a[i].c;
                if(!v[y] && b[y]<=t)
                {
                    v[y]=true;
                    q[ed++]=y;
                    if(ed>n) ed=1;
                }
            }
        }
        v[x]=false;
        st++;
        if(st>n) st=1;
    }
    if(f[n]<k) return true;
    return false;
}

int main()
{
    scanf("%d %d %d",&n,&m,&k);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&b[i]);
        r=max(r,b[i]);
    }
    l=max(b[1],b[n]);
    for(int i=1;i<=m;i++)
    {
        int x,y,c;
        scanf("%d %d %d",&x,&y,&c);
        ins(x,y,c);
        ins(y,x,c);
    }
    if(!spfa(INF)) {printf("AFK");return 0;}
    while(l<=r)
    {
        int mid=(l+r)/2;
        if(spfa(mid))
        {
            r=mid-1;
            ans=mid;
        }
        else l=mid+1;
    }
    printf("%d",ans);
}
阅读更多

没有更多推荐了,返回首页