大神总结的思路果然不一样,可以好好看看挑战,求最大值的最小值,就是二分!!!
那剩下的就很简单了,直接每次dijkstra就行了。
二分最后我有时候懒得判断,就把l-1页判断一次。。。也是个好方法
#include <bits/stdc++.h>
using namespace std;
#define res register int
#define ll long long
#define inf 0x3f3f3f3f
const int maxn=1e4+5;
int N,M,B,ans=1,flag=0;
struct Node{
int num,blood,Max;
};
int cost[maxn],head[maxn],vis[maxn],Max[maxn];
struct edge{
int to,next,val;
}e[50005*2];
void add(int x,int y,int val){
e[ans].to=y;
e[ans].val=val;
e[ans].next=head[x];
head[x]=ans++;
}
bool operator<(const Node a,const Node b){
if(a.blood!=b.blood) return a.blood<b.blood;
else return a.Max>b.Max;
}
bool dij(int n)
{
int xue[maxn];
memset(xue,0,sizeof(xue));
xue[1]=B;
int num[maxn];
for(res i=1;i<=N;i++)
num[i]=cost[i];
int flag1=0;
priority_queue<Node> q;
q.push((Node){1,B,cost[1]});
memset(vis,0,sizeof(vis));
xue[1]=B;
while(!q.empty()){
Node now=q.top();
q.pop();
int x=now.num;
if(vis[x]||cost[x]>n) continue;
vis[x]=1;
for(res i=head[x];i;i=e[i].next){
int y=e[i].to;
if(cost[y]>n) continue;
if(xue[y]<xue[x]-e[i].val){
xue[y]=xue[x]-e[i].val;
num[y]=max(num[y],num[x]);
if(N==y){
flag1=1;
break;
}
q.push((Node){y,xue[y],num[y]});
}
}
if(flag1) break;
}
if(flag1) return true;
else return false;
}
int main()
{
scanf("%d%d%d",&N,&M,&B);
int Maxone=0;
for(res i=1;i<=N;i++){
scanf("%d",&cost[i]);
Maxone=max(Maxone,cost[i]);
}
int from,to,val;
for(res i=0;i<M;i++){
scanf("%d%d%d",&from,&to,&val);
add(from,to,val);
add(to,from,val);
}
int l=cost[N],r=Maxone;
int flag1=-1;
while(l<=r){
int mid=(l+r)>>1;
if(dij(mid)){
flag1=0;
r=mid-1;
flag=1;
}else{
flag1=1;
l=mid+1;
}
}
if(0==flag) printf("AFK");
else{
if(dij(l-1)) printf("%d",l-1);
else printf("%d",l);
}
return 0;
}