题目背景

在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量

有一天他醒来后发现自己居然到了联盟的主城暴风城

在被众多联盟的士兵攻击后,他决定逃回自己的家乡奥格瑞玛

题目描述

在艾泽拉斯,有\(n\)个城市。编号为\(1,2,3,\dots,n\)。

城市之间有\(m\)条双向的公路,连接着两个城市,从某个城市到另一个城市,会遭到联盟的攻击,进而损失一定的血量。

每次经过一个城市,都会被收取一定的过路费(包括起点和终点)。路上并没有收费站。

假设\(1\)为暴风城,\(n\)为奥格瑞玛,而他的血量最多为\(b\),出发时他的血量是满的。

歪嘴哦不希望花很多钱,他想知道,在可以到达奥格瑞玛的情况下,他所经过的所有城市中最多的一次收取的费用的最小值是多少。

输入格式

第一行\(3\)个正整数,\(n\),\(m\),\(b\)。分别表示有\(n\)个城市,\(m\)条公路,歪嘴哦的血量为\(b\)。

接下来有\(n\)行,每行\(1\)个正整数,\(f_i\)。表示经过城市\(i\),需要交费\(f_i\)元。

再接下来有\(m\)行,每行3个正整数,\(a_i\),\(b_i\),\(c_i\)\((1 \le a_i,b_i \le n)\)。表示城市\(a_i\)和城市\(b_i\)之间有一条公路,如果从城市\(a_i\)到城市\(b_i\),或者从城市\(b_i\)到城市\(a_i\),会损失\(c_i\)的血量。

输出格式

仅一个整数,表示歪嘴哦交费最多的一次的最小值。

如果他无法到达奥格瑞玛,输出\(\text{AFK}\)。

输入输出样例

输入 #1

4 4 8
8
5
6
10
2 1 2
2 4 1
1 3 4
3 4 3

输出 #1

10

说明/提示

对于\(60%\)的数据,满足\(n \le 200,m \le 10^4,b \le 200\)

对于\(100%\)的数据,满足\(n \le 10^4\),\(m \le 5 \times 10^4\),\(b \le 10^9\),满足\(c_i \le10^9,f_i \le 10^9\),可能有两条边连接着相同的城市。

血量为0的时候,视为可以通过.


解题报告

题意理解

这道题目,让我们满足两个条件.

  1. 血量充足,也就是路径消耗要小于血量最大值.

  2. 这条路径上经过的点,最大点权最小.

  3. 从起点到终点


算法解析

如果说排除,血量因素,这道题目是非常显然的最短路径问题.

但是我们现在多了一个限制条件,那么该如何是好?

我们知道,如果说我们的最终答案是\(x_1\),也就是说答案路径上最大点的点权为\(x_1\).

现在有一个值\(x_2\),表示限制目标答案路径上最大点的点权为\(x_2\)

\[若x_1<x_2,显然x_2这个条件是可以满足的
\]

同理,我们也可以推断出.

\[若x_1>x_2,显然x_2这个条件是无法满足的,因为题目的答案是x_1,而不是x_2.
\]

综上所述,我们不难得出结论.

这道题目可以,二分最大点权,也就是二分答案

既然如此,我们的判断\(check\)函数,如何处理呢?

我们可以用最短路算法作为判断.以血量作为权值.

转移,则是满足.这条边抵达的终点\(y\),需要满足\(y<=mid\)

然后这道题目就这样解决了.


代码解析

#include <bits/stdc++.h>
using namespace std;
const int N=1e4+20,M=5e4+20;
#define int long long//这道题目数据范围有点大,所以为了抱歉,我们选择long long
int n,m,b,f[N],l,r,head[M],edge[M<<1],Next[M<<1],ver[M<<1],tot,vis[N],dis[N];
inline int Spfa(int mid)
{
memset(vis,false,sizeof(vis));
memset(dis,0x3f,sizeof(dis));
queue<int> q;
q.push(1);
dis[1]=0;
if (f[1]>mid)//初始点也要判断
return false;
while(q.size())
{
int now=q.front();
q.pop();
vis[now]=false;
for(int i=head[now]; i; i=Next[i])
{
int y=edge[i],w=dis[now]+ver[i];
if (dis[y]>w && f[y]<=mid)//目标点点权不可以大于限制值
{
dis[y]=w;
if (!vis[y])
{
q.push(y);
vis[y]=1;
}
}
}
}
return dis[n]<=b;//需要满足血量花费不可以大于最大花费
}
inline void add_edge(int a,int b,int c)
{
edge[++tot]=b;
ver[tot]=c;
Next[tot]=head[a];
head[a]=tot;
}
inline void init()
{
scanf("%lld%lld%lld",&n,&m,&b);
for(int i=1; i<=n; i++)
{
scanf("%lld",&f[i]);
r=max(f[i],r);//最大点权
}
for(int i=1; i<=m; i++)
{
int a,b,c;
scanf("%lld%lld%lld",&a,&b,&c);
add_edge(a,b,c);
add_edge(b,a,c);//建立无向图
}
while(l<r)//二分
{
int mid=l+r>>1;
if (Spfa(mid))
r=mid;
else
l=mid+1;
}
if (!Spfa(r))//无解
puts("AFK");
else
printf("%lld\n",r);
}
signed main()
{
init();
return 0;
}

洛谷P1462 通往奥格瑞玛的道路(SPFA+二分答案)的更多相关文章

  1. 洛谷 P1462 通往奥格瑞玛的道路(二分答案,堆优化dijkstra)

    传送门 解题思路 首先看题目问题,求经过的所有城市中最多的一次收取的费用的最小值是多少.一看“最大值最小”就想到了二分答案. 在读一遍题目,就是二分收取的费用,然后对于每一个二分的费用,跑一边最短路, ...

  2. 洛谷P1462 通往奥格瑞玛的道路(二分+spfa,二分+Dijkstra)

    洛谷P1462 通往奥格瑞玛的道路 二分费用. 用血量花费建图,用单源最短路判断 \(1\) 到 \(n\) 的最短路花费是否小于 \(b\) .二分时需要不断记录合法的 \(mid\) 值. 这里建 ...

  3. luogu P1462 通往奥格瑞玛的道路--spfa+二分答案

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

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

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

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

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

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

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

  7. P1462 通往奥格瑞玛的道路(二分答案+最短路)

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

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

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

  9. 洛谷P1462通往奥格瑞玛的道路——二分答案最短路

    题目:https://www.luogu.org/problemnew/show/P1462 最大值最小问题,二分答案. 代码如下: #include<iostream> #include ...

随机推荐

  1. 解决Linux:Too many levels of symbolic links

    Too many levels of symbolic links 解决:创建链接时使用绝对路径

  2. Java学习笔记-枚举类

    实例有限且固定的类成为枚举类 枚举类的实现 早期时候的实现形式: public static final int SEASON_SPRING = 1; public static final int ...

  3. C#实现多线程的方式:Task——任务

    简介 .NET 4包含新名称空间System.Threading.Tasks,它 包含的类抽象出了线程功能. 在后台使用ThreadPool. 任务表示应完成的某个单元的工作. 这个单元的工作可以在单 ...

  4. sqlite3数据库修复SQLite-database disk image is malformed

    目录 sqlite3数据库修复SQLite-database disk image is malformed title: sqlite3数据库修复SQLite-database disk image ...

  5. 36.HTTP协议

    HTTP简介 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送 ...

  6. java中JDBC是什么?

    [学习笔记] JDBC是什么? JDBC即(java database connectivity数据连接).JDBC是Sun公司编的一堆类和方法,都封装在java.sql包中.你可以利用这堆类和方法来 ...

  7. centos 安装go

    [root@golong-learning src]# wget https://dl.google.com/go/go1.12.7.linux-amd64.tar.gz # 下载 [root@gol ...

  8. Java实现无向图的建立与遍历

    一.基于邻接矩阵表示法的无向图 邻接矩阵是一种利用一维数组记录点集信息.二维数组记录边集信息来表示图的表示法,因此我们可以将图抽象成一个类,点集信息和边集信息抽象成类的属性,就可以在Java中描述出来 ...

  9. (MVC — — Demo)客户管理系统的开发日志

    点击一下 目录 第一步:搭建开发环境 第二步:层次包(按照三层架构思想写) 第四步:开发(utils)工具包 第四步:开发 Dao 层 第五步:开发 services 层 第六步:开发 factory ...

  10. EffectiveC++

    宁可以编译器替换预处理器 define 不被视为语言的一部分,因此也就有可能在预处理阶段被优化掉,导致相关变量出现错误. #define ASPECT_RATIO 1.63 //可以尝试将其替换为 c ...