洛谷P1462 通往奥格瑞玛的道路(二分+spfa,二分+Dijkstra)
二分费用。
用血量花费建图,用单源最短路判断 \(1\) 到 \(n\) 的最短路花费是否小于 \(b\) 。二分时需要不断记录合法的 \(mid\) 值。
这里建议使用while(l <= r),会避免出现答案为 \(r\) 时和答案AFK搞混,样例就是这种情况。
复杂度为 \(O(\log n) \times\) 最短路的复杂度。
- 二分 + Dijkstra版本,复杂度为 \(O(\log n \times E\log E)\) 。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
const long long inf = 1e9+7;
const int maxn = 10005;
const int maxm = 50005;
int n, m, l, r, ai, bi, tot, head[maxn], vis[maxn], f[maxn];
long long b, ci, dist[maxn];
struct node{
int to, nex;
long long cost;
}edge[2 * maxm];
struct G{
int id;
long long cost;
G(){}
G(int _id, long long _cost){
id = _id; cost = _cost;
}
/******/
bool operator < (const G & _G) const {
return cost > _G.cost;
}
}now;
inline void addedge(int u, int v, long long w){
edge[++tot].to = v;
edge[tot].cost = w;
edge[tot].nex = head[u];
head[u] = tot;
}
int dijkstra(int c)
{
for(int i = 1; i <= n; i++) vis[i] = 0, dist[i] = inf;
priority_queue<G> q;
while(!q.empty()) q.pop();
q.push(G(1, 0));
dist[1] = 0;
while(!q.empty()){
now = q.top(); q.pop();
if(vis[now.id] == 1) continue;
vis[now.id] = 1;
for(int j = head[now.id]; j > 0; j = edge[j].nex){
int tmp = edge[j].to;
if(vis[tmp] == 0 && dist[tmp] > dist[now.id] + edge[j].cost && f[tmp] <= c){
dist[tmp] = dist[now.id] + edge[j].cost;
q.push(G(tmp, dist[tmp]));
}
}
}
if(dist[n] < b) return 1;
else return 0;
}
int main()
{
scanf("%d%d%lld", &n, &m, &b);
for(int i = 1; i <= n; i++){
scanf("%d", &f[i]);
r = max(r, f[i]);
}
for(int i = 1; i <= m; i++){
scanf("%d%d%lld", &ai, &bi, &ci);
addedge(ai, bi, ci);
addedge(bi, ai, ci);
}
int ans = 0;
while(l <= r){
int mid = (l + r) >> 1;
if(dijkstra(mid)) ans = mid, r = mid - 1;
else l = mid + 1;
}
if(ans == 0) printf("AFK\n");
else printf("%d\n", ans);
return 0;
}
- 二分 + spfa版本,复杂度为 \(O(\log n \times kE)\) ,\(k\) 通常为 \(2\) 。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
const long long inf = 1e9+7;
const int maxn = 10005;
const int maxm = 50005;
int n, m, l, r, ai, bi, tot, head[maxn], vis[maxn], f[maxn];
long long b, ci, dist[maxn];
struct node{
int to, nex;
long long cost;
}edge[2 * maxm];
queue<int> q;
inline void addedge(int u, int v, long long w){
edge[++tot].to = v;
edge[tot].cost = w;
edge[tot].nex = head[u];
head[u] = tot;
}
int spfa(int c){
for(int i = 1; i <= n; i++) dist[i] = inf, vis[i] = 0;
q.push(1); vis[1] = 1; dist[1] = 0;
while(!q.empty()){
int now = q.front();
q.pop();
vis[now] = 0;
for(int i = head[now]; i > 0; i = edge[i].nex){
int v = edge[i].to;
if(dist[v] > dist[now] + edge[i].cost && f[v] <= c){
dist[v] = dist[now] + edge[i].cost;
if(vis[v] == 0){
/******/
vis[v] = 1;
q.push(v);
}
}
}
}
if(dist[n] < b) return 1;
else return 0;
}
int main()
{
scanf("%d%d%lld", &n, &m, &b);
for(int i = 1; i <= n; i++){
scanf("%d", &f[i]);
r = max(r, f[i]);
}
for(int i = 1; i <= m; i++){
scanf("%d%d%lld", &ai, &bi, &ci);
addedge(ai, bi, ci);
addedge(bi, ai, ci);
}
int ans = 0;
while(l <= r){
int mid = (l + r) >> 1;
if(spfa(mid)) ans = mid, r = mid - 1;
else l = mid + 1;
}
if(ans == 0) printf("AFK\n");
else printf("%d\n", ans);
return 0;
}
洛谷P1462 通往奥格瑞玛的道路(二分+spfa,二分+Dijkstra)的更多相关文章
- 洛谷 P1462 通往奥格瑞玛的道路(spfa+二分搜索)(4boy)
原题:http://www.luogu.org/problem/show?pid=1462#sub 4boy: 大意:给出n个城市,有m条路,每经过一个城市都要交钱,每经过一条道路都要扣HP,有HP上 ...
- 洛谷 P1462 通往奥格瑞玛的道路 解题报告
P1462 通往奥格瑞玛的道路 题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡 ...
- 洛谷——P1462 通往奥格瑞玛的道路
P1462 通往奥格瑞玛的道路 题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡 ...
- 洛谷 P1462 通往奥格瑞玛的道路 题解
P1462 通往奥格瑞玛的道路 题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡 ...
- 洛谷 P1462 通往奥格瑞玛的道路
洛谷 题意:要求在限定油耗内,求最小花费的最大值. 求最小值最大很容易想到二分答案.所以我们往二分的方向去想. 我们二分一个费用,然后要保证到终点时满足限定油耗,所以跑最短路. 不过松弛条件要改一下: ...
- 洛谷P1462 通往奥格瑞玛的道路
题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡奥格瑞玛 题目描述 在艾泽拉斯, ...
- 洛谷P1462 通往奥格瑞玛的道路[二分答案 spfa 离散化]
题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡奥格瑞玛 题目描述 在艾泽拉斯, ...
- 洛谷P1462 通往奥格瑞玛的道路(SPFA+二分答案)
题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡奥格瑞玛 题目描述 在艾泽拉斯, ...
- 洛谷 P1462 通往奥格瑞玛的道路——二分+spfa
上一波链接 https://www.luogu.org/problem/P1462 这道题我们考虑二分答案 然后每次跑一次spfa判断是否能够到达n点 tips:在不考虑负权边的前提下我们写最短路最好 ...
随机推荐
- 腾讯视频的手机端的地址和PC端的地址是不一样的
腾讯视频的手机端的地址和PC端的地址是不一样的,所以使用iframe的时候记得要使用手机端的地址
- 2019年华南理工大学软件学院ACM集训队选拔赛 Round1
TIps: 1.所有代码中博主使用了scanf和printf作为输入输出 2.代码中使用了define LL long long 所以在声明变量的时候 LL其实就等价于long long 希望这两点 ...
- c++中关于类的长度的猜想
在无意中,我偶然发现了类的长度并不是由函数的类型及个数决定,也并非是2的倍数.4的倍数. 在翻阅资料中,我得出了一些我认为可能的猜想. 我们先来看一串代码 #include<iostream&g ...
- Windows 10更新后无法启动Dolby音频驱动程序
在电脑更新Windows 10 1903版本后,重启出现如下问题: 经查,这与驱动强制签名有关.解决方法如下: 打开"设置"->"更新与安全"->& ...
- BZOJ 1875(DP+矩阵快速幂)
题面 传送门 分析 容易想到根据点来dp,设dp[i][j]表示到i点路径长度为j的方案数 状态转移方程为dp[i][k]=∑(i,j)∈Edp[j][k−1]" role="pr ...
- [Java] 歐付寶金流串接教學
前言: 很多接案的人,都會碰到需要接金流的時候.而歐付寶是個台灣的金流平台. 這邊記錄下,串接的心得.我用的語言是Java, 採liferay這個portal平台,不過這份教學當然適合servlet. ...
- Vue组件通信方式(一)
组件与组件的关系,通常有父子关系,兄弟关系以及隔代关系. 针对不同的场景,如何选用适合的通信方式呢? (一) props/$emit parentComponent ==> childCompo ...
- Python 批量文件下载
python文件 批量下载 .图片批量下载 ,批量请求.爬虫 #==================================================================== ...
- asp.net 关于SessionId
原文:https://www.cnblogs.com/zhang1999/p/7278020.html 登陆页面使用Session存储验证码,导致会话产生SessionId,从而导致会话固定,登陆后用 ...
- 系统盘(c盘)空间清理方法总结(转)
我们一般会把系统安装在C盘,但是使用一段时间后会发现C盘的空间越来越少.尤其我们做开发的,会在电脑中装上很多软件的.比如我的机器上C盘空间15G,平时安装软件时只要可以选择我都会把它装到其他盘的, ...