Luogu P1462 通往奥格瑞玛的道路

暴风城

没想到INF爆int卡了我一个月...

求收取费用最多的一次的最小值,显然是要用二分答案。

二分这个最大费用,每次用dijkstra求一下不经过收取费用大于二分值的城市的前提下的最短路,

并判断这个距离是否在血量范围内。

代码如下

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<queue>
#define MogeKo qwq
using namespace std;
const int maxn = 1e6+10;
const int INF = 0x3f3f3f3f;
int n,m,HP; 
int x,y,z,cnt,ans;
int head[maxn],to[maxn],nxt[maxn],val[maxn];
int dis[maxn],c[maxn];
bool vis[maxn];

void add(int x,int y,int z) {
    to[++cnt] = y;
    nxt[cnt] = head[x];
    head[x] = cnt;
    val[cnt] = z;    
}

void dijkstra(int top) {
    priority_queue < pair<int,int> , vector< pair<int,int> > ,greater< pair<int,int> > > q;
    dis[1] = 0;
    q.push(make_pair(0,1));
    while(!q.empty()) {
        int u = q.top().second;
        q.pop();
        if(vis[u])continue;
        vis[u] = 1;
        for(int i = head[u]; i; i = nxt[i]) {
            int v = to[i];
            if(dis[u] + val[i] < dis[v] && c[v] <= top) {
                dis[v] = dis[u] + val[i];
                q.push(make_pair(dis[v],v));
            }
        }
    }
}

void init(){
    memset(vis,0,sizeof(vis));
    for(int i = 1;i <= n;i++) dis[i] = INF;
}

int BS() {
    int ret;
    long long l = max(c[1],c[n]),r = INF;
    while(l < r){
        long long mid = (l+r)>>1;
        init();
        dijkstra((int)mid);
        if(dis[n] < HP){
            ret = mid;
            r = mid;
        }
        else l = mid+1;
    }
    init();
    dijkstra(ret);
    if(dis[n] >= HP) ret = -1;
    return ret;
}

int main() {
    scanf("%d%d%d",&n,&m,&HP);
    for(int i = 1;i <= n;i++)
        scanf("%d",&c[i]);
    for(int i = 1;i <= m;i++){
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
    }
    ans = BS();
    if(ans!=-1)printf("%d",ans);
    else printf("AFK");
    return 0;
}
View Code

 这道题不禁让我想起了有一次我决定坐狮鹫去远方看一看,然后就到了部落的领地

被等级是特殊符号的NPC和狮鹫围殴致死

为了联盟!!!

原文地址:https://www.cnblogs.com/mogeko/p/10953020.html