P1462 通往奥格瑞玛的道路
分析
本题和Acw中的通信线路,几乎相同。
在通信线路中,我们需要求,从起点到终点的路径中,第k+1大的边权的最小值。
而在本题中,我们要求得是,从起点到终点的路径中,最大点权的最小值
那思路就一下清晰起来了,我们可以去二分答案,枚举这个最大值。
对于枚举的每一个值,我们看一下,对于这个值来说,能否顺利走到最终点。
Ac_Code
//求出所有合法路径中点的最大值
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N = 1e4 + 10,M = 1e5 + 10,INF = 0x3f3f3f3f;
int h[N],e[M],ne[M],w[M],idx;
int v[N],dist[N],vv[N];
bool st[N];
int n,m,B;
void add(int a,int b,int c)
{
e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++;
}
bool spfa(int mid)
{
memset(st,0,sizeof st);
memset(dist,0x3f,sizeof dist);
queue<int> q;
q.push(1);
st[1]=1;
dist[1]=0;
while(q.size())
{
auto t = q.front();
q.pop();
if(v[t]>mid) return 0;
st[t]=0;
for(int i=h[t];~i;i=ne[i])
{
int j = e[i];
if(dist[j]>dist[t]+w[i]&&v[j]<=mid)
{
dist[j]=dist[t]+w[i];
if(!st[j])
{
st[j]=1;
q.push(j);
}
}
}
}
if(dist[n]<=B) return 1;
return 0;
}
int main()
{
cin>>n>>m>>B;
memset(h,-1,sizeof h);
for(int i=1;i<=n;i++) cin>>v[i],vv[i]=v[i];
while(m--)
{
int a,b,c;
cin>>a>>b>>c;
add(a,b,c),add(b,a,c);
}
sort(vv+1,vv+n+1);
if(!spfa(vv[n])){
printf("AFK\n");return 0;}
int l = 1,r = n,ans = vv[n];
while(l<r){
int mid = l + r>> 1;
if(spfa(vv[mid]))
{
ans = vv[mid];
r=mid;
}
else l = mid + 1;
}
cout<<ans<<endl;
return 0;
}

浙公网安备 33010602011771号