洛谷 P1951 收费站_NOI导刊2009提高(2) 最短路+二分
题面
题目链接
其实还有一道双倍经验
题目描述
在某个遥远的国家里,有n个城市。编号为1,2,3,…,n。
这个国家的政府修建了m条双向的公路。每条公路连接着两个城市。沿着某条公路,开车从一个城市到另一个城市,需要花费一定的汽油。
开车每经过一个城市,都会被收取一定的费用(包括起点和终点城市)。所有的收费站都在城市中,在城市间的公路上没有任何的收费站。
小红现在要开车从城市u到城市v(1 $ \leq u,v \leq n $ )。她的车最多可以装下 $ s $ 升的汽油。在出发的时候,车的油箱是满的,并且她在路上不想加油。
在路上,每经过一个城市,她都要交一定的费用。如果某次交的费用比较多,她的心情就会变得很糟。所以她想知道,在她能到达目的地的前提下,她交的费用中最多的一次最少是多少。这个问题对于她来说太难了,于是她找到了聪明的你,你能帮帮她吗?
输入输出格式
输入格式
第一行5个正整数, $ n,m,u,v,s $ ,分别表示有 $ n $ 个城市, $ m $ 条公路,从城市 $ u $ 到城市 $ v $ ,车的油箱的容量为 $ s $ 升。
接下来的有 $ n $ 行,每行1个整数, $ f_i $ 表示经过城市 $ i $ ,需要交费 $ f_i $ 元。
再接下来有 $ m $ 行,每行3个正整数,$ a_i,b_i,c_i (1 \leq a_i,b_i \leq n) $ ,表示城市 $ a_i $ 和城市 $ b_i $ 之间有一条公路,如果从城市 $ a_i $ 到城市 $ b_i $ ,或者从城市 $ b_i $ 到城市 $ a_i $ ,需要 $ c_i $ 升的汽油。
输出格式
仅一个整数,表示小红交费最多的一次的最小值。
如果她无法到达城市 $ v $ ,输出-1
输入输出样例
输入样例:
4 4 2 3 8
8
5
6
10
2 1 2
2 4 1
1 3 4
3 4 3
输出样例:
8
说明
【数据规模】
对于60%的数据,满足 $ n \leq 200,m \leq 10000,s \leq 200 $
对于100%的数据,满足 $ n \leq 10000,m \leq 50000,s \leq 1000000000 $
对于100%的数据,满足 $ c_i \leq 1000000000,f_i \leq1000000000, $ 可能有两条边连接着相同的城市。
【时空限制】
1000ms,128M
思路
首先看题目的问法,求最大值的最小,可以考虑到二分答案
首先假定当答案是x,那么他肯定要满足如果不经过交费超过x的点,跑一遍从u到v的最短路一定小于总油量
于是可以根据此多次跑最短路了
AC代码
#include<bits/stdc++.h>
const int maxn=10010;
const int maxm=50010;
using namespace std;
int n,m,st,ed,W,wt[maxn];
int tot,to[maxm<<1],nxt[maxm<<1],head[maxn],len[maxm<<1];
int l,r,dis[maxn];
priority_queue< pair<int,int> > q;
bool vis[maxn],b;
void Dijkstra(int mx)
{
for(int i=1;i<=n;i++) dis[i]=INT_MAX/2;
for(int i=1;i<=n;i++) vis[i]=false;
dis[st]=0;
q.push(make_pair(0,st));
while(!q.empty())
{
int u=q.top().second;
q.pop();
if(vis[u]) continue;
vis[u]=true;
for(int i=head[u];i;i=nxt[i])
{
int v=to[i];
if(wt[v]>mx) continue;
if(dis[u]+len[i]<dis[v])
{
dis[v]=dis[u]+len[i];
q.push(make_pair(-dis[v],v));
}
}
}
}
int main()
{
scanf("%d%d%d%d%d",&n,&m,&st,&ed,&W);
for(int i=1;i<=n;i++)
{
scanf("%d",&wt[i]);
r=max(r,wt[i]);
}
for(int i=1;i<=m;i++)
{
int u,v,w;scanf("%d%d%d",&u,&v,&w);
to[++tot]=v;nxt[tot]=head[u];len[tot]=w;head[u]=tot;
to[++tot]=u;nxt[tot]=head[v];len[tot]=w;head[v]=tot;
}
l=max(wt[st],wt[ed]);
do ///不要while! 否则如果wt[st]和wt[ed]相等就不能进循环了
{
int mid=(l+r)>>1;
Dijkstra(mid);
if(dis[ed]>W) l=mid+1;
else r=mid,b=true;
}while(l<r);
if(b) printf("%d",r);
else printf("-1");
return 0;
}
总结
这题第一遍做只得了80分,因为写的是while而不是do while,这个错很隐蔽。。如果l=0肯定就不会出这种情况了(吧)(所以我想说的是这样定左边界很灵性)
另外,判断是否可到终点的时候,放在r这一边也是一时想到(感谢Uranus巨巨)
洛谷 P1951 收费站_NOI导刊2009提高(2) 最短路+二分的更多相关文章
- 洛谷 P1951 收费站_NOI导刊2009提高(2)
题目描述 在某个遥远的国家里,有n个城市.编号为1,2,3,…,n. 这个国家的政府修建了m条双向的公路.每条公路连接着两个城市.沿着某条公路,开车从一个城市到另一个城市,需要花费一定的汽油. 开车每 ...
- 洛谷——P1951 收费站_NOI导刊2009提高(2)
https://www.luogu.org/problem/show?pid=1951 题目描述 在某个遥远的国家里,有n个城市.编号为1,2,3,…,n. 这个国家的政府修建了m条双向的公路.每条公 ...
- [洛谷P1951]收费站_NOI导刊2009提高(2)
题目大意:有一张$n$个点$m$条边的图,每个点有一个权值$w_i$,有边权,询问从$S$到$T$的路径中,边权和小于$s$,且$\max\limits_{路径经过k}\{w_i\}$最小,输出这个最 ...
- luogu P1951 收费站_NOI导刊2009提高(2) |二分答案+最短路
题目描述 在某个遥远的国家里,有n个城市.编号为1,2,3,-,n. 这个国家的政府修建了m条双向的公路.每条公路连接着两个城市.沿着某条公路,开车从一个城市到另一个城市,需要花费一定的汽油. 开车每 ...
- Luogu P1951 收费站_NOI导刊2009提高(2) 二分 最短路
思路:二分+最短路 提交:1次 题解: 二分最后的答案. $ck()$: 对于每次的答案$md$跑$s,t$的最短路,但是不让$c[u]>md$的点去松弛别的边,即保证最短路不经过这个点.最后$ ...
- 洛谷 P1950 长方形_NOI导刊2009提高(2)
传送门 思路 首先定义\(h\)数组,\(h[i][j]\)表示第\(i\)行第\(j\)列最多可以向上延伸多长(直到一个被用过的格子) 然后使用单调栈算出 \(l_i\)和 \(r_i\) ,分别是 ...
- 洛谷 P1950 长方形_NOI导刊2009提高(2) 题解
P1950 长方形_NOI导刊2009提高(2) 题目描述 小明今天突发奇想,想从一张用过的纸中剪出一个长方形. 为了简化问题,小明做出如下规定: (1)这张纸的长宽分别为n,m.小明讲这张纸看成是由 ...
- Luogu P1951 收费站_NOI导刊2009提高(2)
二分答案+堆优Dijkstra 这个题有些巧妙. 首先,因为要在油量耗完之前跑到终点,所以我们可以用最短路.只要从\(s\)出发到\(t\),它的最短距离大于油量,我们就可以断定它一定走不通,直接输出 ...
- 题解 P1951 【收费站_NOI导刊2009提高(2)】
查看原题请戳这里 核心思路 题目让求最大费用的最小值,很显然这道题可以二分,于是我们可以二分花费的最大值. check函数 那么,我们该怎么写check函数呢? 我们可以删去费用大于mid的点以及与其 ...
随机推荐
- 用React实现一个自动生成文章目录的组件
原文地址:小寒的博客 功能介绍 这个组件的效果呐,就是你在浏览这个页面的时候点击右上角的叉叉看到的那个文章目录. 功能很简单,就是根据文章内容自动生成这个目录,可以快速跳转. 需要的知识点 正则 do ...
- 10张图带你深入理解Docker容器和镜像-转
转载:http://dockone.io/article/783 这篇文章希望能够帮助读者深入理解Docker的命令,还有容器(container)和镜像(image)之间的区别,并深入探讨容器和运行 ...
- fastjson对Date类型的格式化
@JSONField(format="yyyy-MM-dd HH:mm:ss.SSS") private Date sendMqDate; //MQ发送时间
- .net面试问题总结
原文://http://blog.csdn.net/wenyan07/article/details/41541489 用.net做B/S结构的系统,您是用几层结构来开发,每一层之间的关系以及为什么要 ...
- python jieba模块详解
借鉴于 [jieba 模块文档] 用于自己学习和记录! jieba 模块是一个用于中文分词的模块 此模块支持三种分词模式 精确模式(试图将句子最精确的切开,适合文本分析) 全模式(把句子在所有可以成词 ...
- 牛客NOIP暑期七天营-TG3 赛后题解
目录 牛客NOIP暑期七天营-提高组3 A-破碎的矩阵 题目描述 link 题解 代码 B-点与面 题目描述 link 题解 代码 C-信息传递 题目描述 link 题解 牛客NOIP暑期七天营-提高 ...
- [Swoole系列入门教程 5] UDP协议和demo
• 客户端服务端没有任何联系 • 指定地址跟端口,不关心消息是否发送成功 • 心跳检测不能影响到客户端• udp建立长连接
- mysql工具使用
mysql -u user_name -p123456 -h host_name -P 3306 -D database_name -e "show full processlist;&qu ...
- JS钩子的机制与实现
[什么是钩子] 接触过WordPress的朋友都知道,WP的程序中可以执行类似钩子的函数,当然是这PHP实现的钩子.在JavaScript中一样可以实现类似的功能. 用一句话来形容一下:钩子是将需要执 ...
- substring() 方法用于提取字符串中介于两个指定下标之间的字符。
substring() 方法用于提取字符串中介于两个指定下标之间的字符. 语法 stringObject.substring(start,stop) 参数 描述 start 必需.一个非负的整数,规定 ...