洛谷P1462 通往奥格瑞玛的道路 二分答案,dijkstra求最短路,堆优化
作者:互联网
将每个城市的所需过路费放在答案数组中,排序,找到起点与终点最大过路费的位置,作为二分的左界,所有城市中最大的过路费作为二分的右界。每次选一个上限花费,高于这个消费的城市就不能选择,dijkstra找耗血最少的路线即最短路,看以这个花费作为上限花费,能不能血量高于0走到终点,如果能r=mid,降低上限消费,如果不能,l=mid+1,提高上限消费,下贴代码。
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e4+5;
const int maxm=1e5+5;
const int inf=1e9+7;
struct que
{
int key,value;
friend bool operator < (que a,que b)
{
return a.value > b.value;
}
};
priority_queue<que>q;
struct node
{
int to,next,len;
}p[maxm];
int head[maxn];
int a[maxn],b[maxn];
int vertex[maxn];
bool vis[maxn];
int n,m,c;
int cnt,ans;
void add(int x,int y,int w)
{
p[++cnt].next=head[x];
p[cnt].to=y;
p[cnt].len=w;
head[x]=cnt;
}
bool check(int top)
{
if(top<a[1])
return false;
for(int i=2;i<=n;i++)
vertex[i]=inf,vis[i]=false;
vis[1]=true;
for(int i=head[1];i;i=p[i].next)
{
int v=p[i].to;
//cout<<v<<endl;
int cost=p[i].len;
//cout<<cost<<endl;
if(vertex[v]>cost&&a[v]<=top)
{
//cout<<a[v]<<endl;
vertex[v]=cost;
q.push({v,cost});
}
}
while(!q.empty())
{
que temp=q.top();
q.pop();
if(vis[temp.key])
continue;
vis[temp.key]=true;
for(int i=head[temp.key];i;i=p[i].next)
{
int v=p[i].to;
int cost=p[i].len;
if(a[v]<=top&&(vertex[v]>(temp.value+cost))&&!vis[v])
{
vertex[v]=temp.value+cost;
q.push({v,vertex[v]});
}
}
}
if(c-vertex[n]>0)
return true;
else
return false;
}
int main()
{
scanf("%d %d %d",&n,&m,&c);
int l,r,mid;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]),b[i]=a[i];
int t1=a[1],t2=a[n];
sort(b+1,b+1+n);
int Ma=-1;
for(int i=1;i<=n;i++)
if(b[i]==t1||b[i]==t2)
{
if(Ma<b[i])
Ma=b[i],l=i;
}
r=n;
for(int i=1;i<=m;i++)
{
int x,y,w;
scanf("%d %d %d",&x,&y,&w);
add(x,y,w);
add(y,x,w);
}
//cout<<b[n]<<endl;
//check(b[n]);
//printf("%d\n",vertex[n]);
if(!check(b[n]))
{
puts("AFK");
return 0;
}
ans=b[n];
while(l<r)
{
mid=(l+r)>>1;
int top=b[mid];
if(check(top))
r=mid,ans=top;
else
l=mid+1;
}
printf("%d\n",ans);
return 0;
}
烟雨落叶
发布了3 篇原创文章 · 获赞 2 · 访问量 16
私信
关注
标签:cnt,瑞玛,洛谷,int,mid,P1462,maxn,value,return 来源: https://blog.csdn.net/weixin_44491423/article/details/104442855