用二分+Dijskra+堆优化写的代码
渴望各位巨佬在百忙之中抽出时间看一下蒟蒻的题!
万分感谢!
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#define N 10005
#define MAXN 1000000005
using namespace std;
struct node{
int num,cost,bloom;
bool operator<(const node&rhs)const{
return cost>rhs.cost;
}
}vex;
int n,m,B;
int V[N],dis[N];
bool vis[N];
vector<node>G[N];
priority_queue<node>pq;
bool check(int level)
{
if (V[1]>level||V[n]>level)return false;
node vex;
vex.num=1;vex.cost=dis[1];vex.bloom=B;
memset(dis,0x3f,sizeof(dis));
memset(vis,0,sizeof(vis));
dis[1]=V[1];
pq.push(vex);
while(!pq.empty())
{
node h=pq.top();pq.pop();
int num=h.num;
if (vis[num])continue;
vis[num]=true;
for (int i=0;i<G[num].size();i++)
{
node j=G[num][i];
if (!vis[j.num] && h.bloom>=j.bloom && j.cost<=level)
{
dis[j.num]=max(j.cost,h.cost);
vex.num=j.num;
vex.cost=dis[j.num];
vex.bloom=h.bloom-j.bloom;
pq.push(vex);
}
}
}
return dis[n]<=level;
}
int main()
{
scanf("%d%d%d",&n,&m,&B);
for (int i=1;i<=n;i++){
scanf("%d",&V[i]);
}
int u,v,bloom,l,r;
for (int i=1;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&bloom);
vex.num=u;vex.cost=V[v];vex.bloom=bloom;
G[v].push_back(vex);
vex.num=v;vex.cost=V[u];
G[u].push_back(vex);
}
l=0;r=MAXN;
int mid;
while(l<r)
{
mid=(l+r)/2;
if (check(mid))r=mid;
else l=mid+1;
}
if (r==MAXN)puts("AFK");
else printf("%d",l);
return 0;
}