P1462 通往奥格瑞玛的道路 link
思路:
首先,看见这个问题,就应该想到二分。
所有类似于“求解所有的最大值中的最小值”的问题,都应该先想一想用二分答案的方法来写。
为什么呢?因为二分答案就是用来求解这种问题的,它通过猜测目前的答案+验证目前答案是否成立来求解,这种“假设已经知道答案”的方法比用题目信息求解答案的方法要优秀很多,而且复杂度也仅仅是加了一个log。
但是还要注意一点,除了这种经典问法以外,还要通过答案是否具有单调性来判断是否可以使用二分答案的方法
不具有单调性的问题是不可以使用这种方法的!
回到本题,我们猜测可以使用二分答案后,再验证:由于 “我们假设需要的钱”越多,能走的点也就越多,可以走到终点的可能性也就越大,所以,这题是完全可以通过二分答案来写的。
然后,我们发现这里有两个变量:血量和费用。至于费用,我们已经用二分答案解决了,现在只需要解决血量的问题。 我们在上面分析了,损失血量是和边绑定在一起的,所有可以把损失血量看做每条边的长度,进而就到了这题的中心——单源最短路。
#include<bits/stdc++.h>
using namespace std;
#define ong long long
const int N=10010;
const int M=100010;
const ong inf=LLONG_MAX/3; //小心爆long long
int n,m,b,u,v;
int l,r,mid;
ong wi; //爆int了
struct node{
int a;
ong dis;
};
bool operator < (node x,node y){
return x.dis>y.dis;
} priority_queue<node> q;
int top,g[N],f[N];
ong dis[N];
bool vis[N];
struct edge{
int adj,nex;
ong w;
}e[M];
void add(int x,int y,ong wor){
e[++top]=(edge){
y,g[x],wor};
g[x]=top;
} void Dijkstra(int maxn){
for(int i=1;i<=n;i++){
dis