题目来源:https://www.luogu.org/problem/show?pid=1462
二分答案+SPFA。
对其要花的费用二分,每次验证是否正确时跑一遍SPFA,只取费用<mid的点。
代码:
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <sstream>
#include <cstdio>
#include <string>
#include <vector>
#include <cmath>
#include <ctime>
#include <stack>
#include <queue>
#include <set>
#include <map>
using namespace std;
const int maxn=1e4+1;
int a[maxn]={0};
struct edge{int t,w;};
vector<edge> v[maxn];
bool inq[maxn]={0};
int dis[maxn]={0};
const int inf=1e9+10;
int main()
{
ios::sync_with_stdio(false);
int n,m,b;
cin>>n>>m>>b;
int l=0,r=inf;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=m;i++)
{
int x,y,z;
cin>>x>>y>>z;
edge p;
p.w=z;p.t=x;v[y].push_back(p);
p.t=y;v[x].push_back(p);
}
while(l<r)
{
int mid=(l+r)/2;
int ok=0;
memset(inq,0,sizeof(inq));
for(int i=1;i<=n;i++)dis[i]=inf;
dis[1]=0;inq[1]=1;
queue<int> q;
q.push(1);
while(!q.empty())
{
int u=q.front();q.pop();
for(int i=0;i<v[u].size();i++)
{
if(a[v[u][i].t]<=mid)
{
if(dis[v[u][i].t]>dis[u]+v[u][i].w)
{
dis[v[u][i].t]=dis[u]+v[u][i].w;
if(!inq[v[u][i].t])
{
q.push(v[u][i].t);
inq[v[u][i].t]=1;
}
}
}
}
inq[u]=0;
}
if(dis[n]>=b)ok=0;
else ok=1;
if(ok)r=mid;
else l=mid+1;
}
if(r==inf)cout<<"AFK";
else cout<<l;
return 0;
}