[LuoguP1462]通往奥格瑞玛的道路($SPFA+$二分)

#(mathcal{color{red}{Description}})

(Link)

有一个图,求其在(1-N)的最短路小于一个给定值下,点权最大值的最小值。

#(mathcal{color{red}{Solution}})

(emmm)这个题也是几天前做的……正在填坑(qwq)

这道题虽然在(Luogu)上显示是和(color{cyan}{A Link})一个难度的,但是要明显简单很多好不好……

正解的话,很显然要二分一个血量…… 因为二分(答案)是有套路的:

1、求最……的……(一般不可以静态求)

2、求什么就二分什么

3、 一般是反着推,就是用二分出的结果去推条件是否满足,或者状态是否合法

于是,二分交费,然后在(check)的时候,由于二分的是最大值,所以比二分的(x)大的就不走,小的可以走,以此为限制条件(SPFA),观察跑出来的最短路是否大于拥有的血量,大的话自然就不合法,小的话自然合法。然后就做完了(qwq)

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#define ll long long
#define to(k) e[k].to

using namespace std ;
const int MAXN = 62050 ;
struct edge{
    ll to, next, v ;
}e[MAXN << 1] ;
queue<ll> q ;
ll head[MAXN << 1], cnt, dist[MAXN], i, k, ct ;
ll base[MAXN], l, r, mid, a, b, c, N, M, K, vis[MAXN], now ;

inline void init(){
    memset(dist, 0x3f, sizeof(dist)), memset(vis, 0, sizeof(vis)) ;
    queue<ll> emt ; swap(q, emt), q.push(1), vis[1] = 1, dist[1] = 0  ;
}
inline bool check(ll x){
    init() ;
    while(!q.empty()){
        now = q.front(), q.pop(), vis[now] = 0 ;
        for(k = head[now]; k ; k = e[k].next){
            if(base[to(k)] > x) continue ;
            if(dist[to(k)] > dist[now] + e[k].v){
                dist[to(k)] = dist[now] + e[k].v ;
                if(!vis[to(k)]){
                    vis[to(k)] = 1 ;
                    q.push(to(k)) ;
                }
            }
        }
    }
    if(dist[N] > K) return 0 ; return 1 ;
}
inline void add(int u, int v, int w){
    e[++cnt].to = v, e[cnt].v = w ;
    e[cnt].next = head[u], head[u] = cnt ;
}
int main(){
    cin >> N >> M >> K ;
    for(i = 1; i <= N; i ++) cin >> base[i] ;
    for(i = 1; i <= M; i ++){
        cin >> a >> b >> c ;
        add(a, b, c), add(b, a, c) ;
    }l = 0, r = 1000000000 ;
    while(l < r){
        mid = (l + r) >> 1 ;
        if(check(mid)) r = mid ;
        else  l = mid + 1 ;
    }
    if(l == 1000000000) cout << "AFK" ;
    else cout << l ;
}

幕后花絮:这个题我特别细心地判了(-1),结果让输出(AFK)……好吧人生就是这样的跌宕起伏(ORZ)……然后现在的我看二分答案就像我当年的我看快速幂一样,绝对不是不会,可以充分体现出我的“OI”思维没有多高……因为常人自然难以理解,(Coder)素质越高,理解起来越简单……现在的状态嘛…大概写出一份二分答案来问题不是很大,但是要做到稔熟于心,也还需要一段路要走啊(qwq)

原文地址:https://www.cnblogs.com/pks-t/p/9368186.html