洛谷P1462 通往奥格瑞玛的道路

二分费用。

用血量花费建图,用单源最短路判断 \(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)的更多相关文章

  1. 洛谷 P1462 通往奥格瑞玛的道路(spfa+二分搜索)(4boy)

    原题:http://www.luogu.org/problem/show?pid=1462#sub 4boy: 大意:给出n个城市,有m条路,每经过一个城市都要交钱,每经过一条道路都要扣HP,有HP上 ...

  2. 洛谷 P1462 通往奥格瑞玛的道路 解题报告

    P1462 通往奥格瑞玛的道路 题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡 ...

  3. 洛谷——P1462 通往奥格瑞玛的道路

    P1462 通往奥格瑞玛的道路 题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡 ...

  4. 洛谷 P1462 通往奥格瑞玛的道路 题解

    P1462 通往奥格瑞玛的道路 题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡 ...

  5. 洛谷 P1462 通往奥格瑞玛的道路

    洛谷 题意:要求在限定油耗内,求最小花费的最大值. 求最小值最大很容易想到二分答案.所以我们往二分的方向去想. 我们二分一个费用,然后要保证到终点时满足限定油耗,所以跑最短路. 不过松弛条件要改一下: ...

  6. 洛谷P1462 通往奥格瑞玛的道路

    题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡奥格瑞玛 题目描述 在艾泽拉斯, ...

  7. 洛谷P1462 通往奥格瑞玛的道路[二分答案 spfa 离散化]

    题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡奥格瑞玛 题目描述 在艾泽拉斯, ...

  8. 洛谷P1462 通往奥格瑞玛的道路(SPFA+二分答案)

    题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡奥格瑞玛 题目描述 在艾泽拉斯, ...

  9. 洛谷 P1462 通往奥格瑞玛的道路——二分+spfa

    上一波链接 https://www.luogu.org/problem/P1462 这道题我们考虑二分答案 然后每次跑一次spfa判断是否能够到达n点 tips:在不考虑负权边的前提下我们写最短路最好 ...

随机推荐

  1. idea 社区版本创建javaweb项目 使用jetty

    idea社区版本 创建javaweb项目后使用jetty启动 <dependencies> <dependency> <groupId>javax.servlet& ...

  2. SpringMvc+Mybatis开发需要的jar包

    SpringMvc+Mybatis开发需要的jar包

  3. day16 django 笔记

    一 jQuery是什么? [1]   jQuery由美国人John Resig创建,至今已吸引了来自世界各地的众多 javascript高手加入其team. [2]   jQuery是继prototy ...

  4. Python 中的作用域?

    Python 中,一个变量的作用域总是由在代码中被赋值的地方所决定. 当 Python 遇到一个变量的话,它会按照这的顺序进行搜索:本地作用域(Local)--->当前作用域被嵌入的本地作用域( ...

  5. service worker介绍

    原文:Service workers explained 译者:neal1991 welcome to star my articles-translator, providing you advan ...

  6. JavaWeb基础工具类——BaseDao

    package dao; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStat ...

  7. HTML导航框架实现

    导航栏界面(html_contents.html) <!DOCTYPE html> <html> <head> <meta charset=” utf-8” ...

  8. 读取FTP上的excel文件,并写入数据库

    今天遇到一些问题,需要从ftp上读取一些excel文件,并需要将excel中的数据写入到数据库,这样就可以通过管理页面查看这些数据. 我将相关工作分为三步,1.从ftp上读取相关文件,并将excel文 ...

  9. 利用docker创建包含需要python包的python镜像

    一.拉取python镜像 需要先安装docker,这里读者自行搜索docker的安装过程,下面我们拉取python镜像:以3.7.4为例 docker pull python:3.7.4 二.进入容器 ...

  10. 封装操作mysql、redis

    封装操作mysql: import pymysql class MyDb: def __init__(self,host,password,user,db,port=3306,charset='utf ...