[JZOI]1251.收费站[二分][最短路]

这篇博客介绍了如何解决一个涉及最短路径和最大费用的问题。小红试图从城市u开往城市v,途中每个城市都有不同的收费,并且车辆油箱限制为s升。博主通过二分搜索在[1, 最大城市收费]范围内找到最小的最大费用。他们首先计算最短路,然后在每次二分迭代中检查路径上的费用是否不超过油箱容量。最终,博客提供了具体的解决方案,包括二分查找和最短路算法的应用。" 88237926,7437669,爬取三大二手车网站新能源车数据,"['爬虫', '数据获取', '网页抓取', '二手车平台']
摘要由CSDN通过智能技术生成

Description

在某个遥远的国家里,有n个城市。编号为1,2,3,……,n。 这个国家的政府修建了m条双向的公路。每条公路连接着两个城市。沿着某条公路,开车从一个城市到另一个城市,需要花费一定的汽油。
开车每经过一个城市,都会被收取一定的费用(包括起点和终点城市)。所有的收费站都在城市中,在城市间的公路上没有任何的收费站。
小红现在要开车从城市u到城市v(1<=u,v<=n)。她的车最多可以装下s升的汽油。在出发的时候,车的油箱是满的,并且她在路上不想加油。
在路上,每经过一个城市,她要交一定的费用。如果她某次交的费用比较多,她的心情就会变得很糟。所以她想知道,在她能到达目的地的前提下,她交的费用中最多的一次最少是多少。这个问题对于她来说太难了,于是她找到了聪明的你,你能帮帮她吗?

Input

第一行5个正整数,n,m,u,v,s。分别表示有n个城市,m条公路,从城市u到城市v,车的油箱的容量为s升。
接下来有n行,每行1个正整数,fi。表示经过城市i,需要交费fi元。 再接下来有m行,每行3个正整数,ai,bi,ci(1<=ai,bi<=n)。表示城市ai和城市bi之间有一条公路,如果从城市ai到城市bi,或者从城市bi到城市ai,需要用ci升汽油。

Output

仅一个整数,表示小红交费最多的一次的最小值。 如果她无法到达城市v,输出-1。

Sample Input

输入样例1
4 4 2 3 8
8
5
6
10
2 1 2
2 4 1
1 3 4
3 4 3
输入样例2
4 4 2 3 3
8
5
6
10
2 1 2
2 4 1
1 3 4
3 4 3

Sample Output

输出样例1
8
输出样例2
-1

Data Constraint

数据规模 对于60%的数据,满足n<=200,m<=19900,s<=200,没有一条边连接着两个相同的城市。
对于100%的数据,满足n<=10000,m<=50000,s<=1000000000,可能有两条边连接着相同的城市。
对于100%的数据,满足ci<=1000000000,fi<=1000000000

Analysis

  • 有n个带权点,m条带权边的无向图。 n ∈ [ 1 , 10000 ] , m ∈ [ 1 , 50000 ] n \in [1,10000],m\in[1,50000] n[1,10000],m[1,50000]
  • 从点u出发到v,经过的所有点点权不得超过一个数,且最短路长度不得超过s
  • 输出这个数的最大值
    对于这种最大值问题,考虑二分答案。

Solution

计算出最大点权作为二分上界,所以答案范围在[1,maxfee]的区间内。
因此我们二分枚举答案检验是否合法:

	//二分答案
	ll ll = 1,rr =  maxfee,ans = -1,mid;
	while(ll<=rr)
	{
   
		mid = (ll+rr)>>1;
		if(dij(u,mid))//检验是否合法
		{
   
			ans = mid;
			rr = mid-1;
		}
		else
			ll = mid+1;
	}

二分后使用最短路算法,更新的时候判断 目标点 的点权是否合法,若不合法则不能用于更新最短路。
那么我们需要对更新的判断语句做一点调整。
dijkstra算法为例进行对比:

if(!vis[v] && dis[v] > dis[u
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值