P1462 通往奥格瑞玛的道路
题目:找最短路径中点权的最大值的最小值
最大值的最小值,最小值的最大值,一般这种题目都会想到二分答案去解决。
所以我们先把所有点权排个序(二分需满足有序性),然后二分点权,跑一遍最短路确认该方案是否可行(走的路径时,边权损失的HP要尽量的小,这样才可能到达最终的点,维护答案即可
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
#define int long long
#define ll int
const int maxn = 1e6+5;
struct Edge{
int u,v,nxt,c;
}edge[maxn<<1];
struct Node{
int u,dis;
bool operator <(const Node &h)const{
return dis > h.dis;
}
};
int head[maxn],tot;
inline void init(){
memset(head,-1,sizeof(head));
tot = 0;
}
inline void addedge(int u,int v,int c){
++tot;
edge[tot] = {
u,v,head[u],c};
head[u] = tot;
}
int f[maxn],ff[maxn];
int dis[maxn];
bool vis[maxn];
bool dijiastra(int u,int v,int fm,int hp){
memset(dis,0x3f,sizeof(dis));
memset(vis,0,sizeof(vis));
dis[u] = 0;
if(fm < ff[u]) return false;
priority_queue<Node> pq; pq.push(Node{
u,0});
while(!pq.empty()){
Node x = pq.top(); pq.pop();
if(vis[x.u]) continue;
vis[x.u] = true;
for(int i = head[x.u]; ~i; i = edge[i].nxt){
Edge &e = edge[i];
if(ff[e.v] > fm) continue;
if(dis[e.v] > dis[x.u] + e.c){
dis[e.v] = dis[x.u] + e.c;
pq.push(Node{
e.v,dis[e.v]});
}
}
}
return dis[v] <= hp;
}
signed main()
{
init();
int n,m,b; cin >> n >> m >> b;
for(int i = 1; i <= n; ++i){
cin >> f[i]; ff[i] = f[i