学而 @ 2018-07-14 16:37:37
代码思路为二分+djstra 第一个测试点手动评测为AFK 洛谷机评为 32766 正确答案为AFK 求解
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define ll long long
using namespace std;
const int N=10010<<1,M=50010<<2;
const ll inf=1<<30;
int read(){
int fl=1,sum=0;char w=getchar();
while(w>'9'||w<'0'){if(w=='-')fl=-1;w=getchar();}
while(w>='0'&&w<='9'){sum=(sum<<3)+(sum<<1)+(w^48);w=getchar();}
return sum*fl;
}
int n,m,b,f[N],to[M],ne[M],w[M],head[M],l,r,mid,tot,s,t;
void add(int x,int y,int ww){
to[++tot]=y,w[tot]=ww,ne[tot]=head[x],head[x]=tot;
to[++tot]=x,w[tot]=ww,ne[tot]=head[y],head[y]=tot;
}
priority_queue< pair<int,int> >q;
ll d[N];
bool v[N];
bool djstra(){//以mid为界 f[y]<=mid
for(int i=1;i<=n;i++)d[i]=inf;
memset(v,0,sizeof(v));
d[s]=0;q.push(make_pair(0,s));
int x,y;
while(!q.empty()){
x=q.top().second;q.pop();
if(v[x]||b-d[x]<=0)continue;v[x]=1;
if(x==t)return 1;
for(int i=head[x];i;i=ne[i]){
y=to[i];
if(f[y]>mid)continue;
if(d[y]>d[x]+w[i]){
d[y]=d[x]+w[i];
// printf("+++++%d %d ",y,d[y]);
// system("pause");
q.push(make_pair(-d[y],y));
}
}
}
return 0;
}
int main(){
freopen("testdata.in","r",stdin);
n=read(),m=read(),b=read();//城市数 公路数 血量
t=1,s=n;
for(int i=1;i<=n;i++){
f[i]=read();//费用
r=max(r,f[i]);
}
l=max(f[1],f[n]);
int u,v,ww;
for(int i=1;i<=m;i++){
u=read(),v=read(),ww=read();
add(u,v,ww);//血量 双边
}
//2分费用 + djstra 损耗血量=距离
int ans;
while(r>=l){
mid=(l+r)>>1;
if(djstra()){
r=mid-1;
ans=mid;
}
else {
l=mid+1;
}
}
if(ans)printf("%d",ans);
else printf("AFK");
return 0;
}