洛谷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:在不考虑负权边的前提下我们写最短路最好 ...
随机推荐
- idea 社区版本创建javaweb项目 使用jetty
idea社区版本 创建javaweb项目后使用jetty启动 <dependencies> <dependency> <groupId>javax.servlet& ...
- SpringMvc+Mybatis开发需要的jar包
SpringMvc+Mybatis开发需要的jar包
- day16 django 笔记
一 jQuery是什么? [1] jQuery由美国人John Resig创建,至今已吸引了来自世界各地的众多 javascript高手加入其team. [2] jQuery是继prototy ...
- Python 中的作用域?
Python 中,一个变量的作用域总是由在代码中被赋值的地方所决定. 当 Python 遇到一个变量的话,它会按照这的顺序进行搜索:本地作用域(Local)--->当前作用域被嵌入的本地作用域( ...
- service worker介绍
原文:Service workers explained 译者:neal1991 welcome to star my articles-translator, providing you advan ...
- JavaWeb基础工具类——BaseDao
package dao; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStat ...
- HTML导航框架实现
导航栏界面(html_contents.html) <!DOCTYPE html> <html> <head> <meta charset=” utf-8” ...
- 读取FTP上的excel文件,并写入数据库
今天遇到一些问题,需要从ftp上读取一些excel文件,并需要将excel中的数据写入到数据库,这样就可以通过管理页面查看这些数据. 我将相关工作分为三步,1.从ftp上读取相关文件,并将excel文 ...
- 利用docker创建包含需要python包的python镜像
一.拉取python镜像 需要先安装docker,这里读者自行搜索docker的安装过程,下面我们拉取python镜像:以3.7.4为例 docker pull python:3.7.4 二.进入容器 ...
- 封装操作mysql、redis
封装操作mysql: import pymysql class MyDb: def __init__(self,host,password,user,db,port=3306,charset='utf ...