洛谷 P1462 通往奥格瑞玛的道路 二分+Dijkstra优先队列优化

洛谷 P1462 通往奥格瑞玛的道路 二分+Dijkstra优先队列优化

代码如下:

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<cmath>
#include<queue>
#include<string>
#include<vector>
#define MAX 10010
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;

int n,m,b,maxl=-1;//n为顶点数,m为边的数量,b为血量,maxl为可能收取的最大费用
int visit[MAX],dis[MAX];
int money[MAX];//经过某个城市所要收取的费用


struct edge{//存储边
  int to;//边的指向
  int cost;//边的权值
};

vector<edge> adj[MAX];
typedef pair<int,int> p; //first是最短距离,second是顶点的编号

struct cmp{//优先队列的cmp是一个类
    bool operator()(p a,p b) {
        return a.first>b.first;
    }
};

//priority_queue<p,vector<p>,cmp > q;

bool check(int x){
    if(money[1]>x) return false;//如果第一个点就不能走,直接返回false
    for(int i=0;i<MAX;i++){
        visit[i]=0;
        dis[i]=INF;
    }
    dis[1]=0;
    priority_queue<p,vector<p>,cmp > q;
    q.push(p(0,1));//将源结点放入优先队列
    while(!q.empty()){
        p top=q.top();
        q.pop();
        int u=top.second;
        if(visit[u]==0){
            visit[u]=1;
            for(int i=0;i<adj[u].size();i++){
                edge e=adj[u][i];
                if(money[e.to]>x) continue;//如果新扩展的点不符合要求,继续寻找
                if(dis[e.to]>dis[u]+e.cost){
                    dis[e.to]=dis[u]+e.cost;
                    q.push(p(dis[e.to],e.to));
                }
                if(e.to==n){//如果已经到达了n
                    if(dis[n]>=b) return false;//说明血量不足
                    else return true;//说明血量充足
                }
            }
        }
    }
    return false;
}

int main(){
  cin>>n>>m>>b;
  for(int i=1;i<=n;i++){
      cin>>money[i];
      maxl=max(maxl,money[i]);
  }
  int a,c,len;
  for(int i=0;i<m;i++){
    cin>>a>>c>>len;
    edge e;
    e.to=c;
    e.cost=len;
    adj[a].push_back(e);//adj[a]是从顶点a出发的边的集合
    e.to=a;
    adj[c].push_back(e);//adj[b]是从顶点b出发的边的集合
  }

  //二分
  int l=1,r=maxl,ans=-1;
  while(l<=r){
        int mid=(l+r)/2;
        if(check(mid)) ans=mid,r=mid-1;//说明mid大了,更新ans
        else l=mid+1;
    }
    if(ans==-1) printf("AFK");//如果每次都没有扩展成功说明不能到达
    else printf("%d\n", ans);
  return 0;
}
发布了253 篇原创文章 · 获赞 15 · 访问量 7977

猜你喜欢

转载自blog.csdn.net/weixin_44123362/article/details/103931830
今日推荐