看到最大的最小值應該想到二分答案,這樣就解決了最小點權的問題,判血量就很好說,直接比較就行,
一個點是二分點權數組,複製一份然後排序,二分下標,速度較快
這麼簡單的題我竟然寫了這麼長時間
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define ll long long using namespace std; const int maxn=10005; const int maxm=50005; int n,m,b,w[maxn],ans,f[maxn]; int head[maxn],cnt; struct node{ int v,w,nxt; }e[maxm*2]; ll d[maxn];bool v[maxn]; void add(int u,int v,int w){e[++cnt].v=v;e[cnt].w=w;e[cnt].nxt=head[u];head[u]=cnt;} bool spfa(int top){ memset(d,0x3f,sizeof(d)); memset(v,0,sizeof(v)); queue<int>q; d[1]=0;v[1]=1;q.push(1); while(!q.empty()){ int x=q.front();q.pop();v[x]=0; for(int i=head[x];i;i=e[i].nxt){ int y=e[i].v,z=e[i].w; if(d[y]>d[x]+z && w[y]<=top){ d[y]=d[x]+z; if(!v[y])q.push(y),v[y]=1; } } } if(d[n]<=b)return 1; else return 0; } int main() { scanf("%d%d%d",&n,&m,&b); for(int i=1;i<=n;i++)scanf("%d",&w[i]),f[i]=w[i]; for(int i=1,x,y,z;i<=m;i++){ scanf("%d%d%d",&x,&y,&z); add(x,y,z);add(y,x,z); } sort(f+1,f+1+n); if(!spfa(0x7fffffff)){printf("AFK ");return 0;}//無限制都不能到達,血量不夠 int l=1,r=n;//二分f數組,比較快 while(l<=r){ int mid=(l+r)>>1; if(spfa(f[mid]))r=mid-1,ans=f[mid]; else l=mid+1; } printf("%d ",ans); }