意思就是费用的最大值最小
那么我们对最大费用进行二分,按此跑最短路,累计扣减血量进行比较即可
1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 const int N=10010,M=100010; 5 long long n,m,hp,tmp,sum[N],que[N],vis[N],w[N]; 6 int size,head[M],next[M],to[M],b[M]; 7 int read(){ 8 int sum=0; 9 char ch=getchar(); 10 while (ch<'0'||ch>'9') 11 ch=getchar(); 12 while (ch>='0'&&ch<='9'){ 13 sum=sum*10+ch-'0'; 14 ch=getchar(); 15 } 16 return sum; 17 } 18 void uni(int x,int y,int d){ 19 size++; 20 next[size]=head[x]; 21 head[x]=size; 22 to[size]=y; 23 b[size]=d; 24 } 25 int spfa(int mo){ 26 for (int i=1;i<=n;i++){ 27 vis[i]=0; 28 sum[i]=tmp; 29 } 30 int l=0,r=1; 31 que[1]=1; 32 vis[1]=1; 33 sum[1]=0; 34 while (l<=r){ 35 l=(l+1)%10000; 36 int x=que[l]; 37 vis[x]=0; 38 for (int e=head[x];e;e=next[e]){ 39 int y=to[e]; 40 if (w[y]<=mo&&sum[x]+b[e]<sum[y]){ 41 sum[y]=sum[x]+b[e]; 42 if (!vis[y]){ 43 r=(r+1)%10000; 44 que[r]=y; 45 vis[y]=1; 46 } 47 } 48 } 49 } 50 if (sum[n]<=hp&&sum[n]!=tmp)//* 51 return 1; 52 return 0; 53 } 54 int main(){ 55 int x,y,c; 56 size=0; 57 n=read(); 58 m=read(); 59 hp=read(); 60 for (int i=1;i<=n;i++){ 61 w[i]=read(); 62 if (tmp<w[i]) 63 tmp=w[i]; 64 } 65 for (int i=1;i<=m;i++){ 66 x=read(); 67 y=read(); 68 c=read(); 69 uni(x,y,c); 70 uni(y,x,c); 71 } 72 int l=0,r=tmp; 73 if (!spfa(r)){ 74 printf("AFK"); 75 return 0; 76 } 77 while (l<r){ 78 int mid=(l+r)>>1; 79 if (spfa(mid)) 80 r=mid; 81 else 82 l=mid+1; 83 } 84 printf("%d",l); 85 return 0; 86 }