[JZOI]1251.收费站[二分][最短路]
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] + map[u][v])//以基点更新最短路
dis[v] = dis[u] + map[u][v];//这里使用了简朴的写法,仅仅用于对比
那么我们添加限定条件后,只是简单地变为
if(!vis[v] && cost[v] <= ans && dis[v] > dis[u] + map[u][v])
dis[v] = dis[u] + map[u][v];
这个ans即我们正在验证的答案。最后求完最短路,判定答案是否合法就简单了:
if(dis[v] > s) return false;
因为dis数组初始化为无穷大,所以无论是未访问到的情况还是超过给出最短路限定长度s的情况都能这样排掉。
到此,本题就结束了。
但其实,还有最后一个点,卡了我几十分钟的一个神奇问题(当然是我太菜了)
还需要判断起点的点权是否合法(捂脸)
if(cost[start] > maxf) return false;
就这么一行……
Code
- 链式前向星存图
- 根优化dijkstra求最短路
- 二分查找答案
#include <cstdio>
#include <cstring>
#include <queue>
typedef long long ll;
using namespace std;
//functions
inline void add(const ll&,const ll&,const ll&);
void read(ll&);
ll init();
bool dij(ll,ll);
//end
struct node
{
ll d,to,next;
node(ll q,ll w,ll e)
{to=q,next=w,d=e;}
node(){}
}lines[100010];
ll head[10010];
ll cost[10010];
ll dis[10010];
ll n,m,u,v,s;
int main()
{
ll maxfee = init();//初始化
//二分答案
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;
}
printf("%d",ans);
return 0;
}
ll init()
{
read(n);read(m);read(u);read(v);read(s);
ll maxfee = 0;
for(int i = 1;i<=n;++i)
{
read(cost[i]);
if(cost[i] > maxfee)
maxfee = cost[i];
}
ll ai,bi,ci;
for(int i = 1;i<=m;++i)
{
read(ai);
read(bi);
read(ci);
add(ai,bi,ci);
add(bi,ai,ci);
}
return maxfee;
}
void read(ll &r)
{
static char c;r = 0;
for(c=getchar();c>'9'||c<'0';c=getchar());
for(;c>='0'&&c<='9';r=(r<<1)+(r<<3)+c-48,c=getchar());
}
inline void add(const ll &x,const ll &y,const ll &d)
{
static ll tot = 0;
lines[++tot] = node(y,head[x],d);
head[x] = tot;
}
ll vis[10010];
struct Point
{
ll num,dis;
bool operator<(const Point &b) const
{
return dis>b.dis;
}
Point(){}
Point(ll an,ll ad){num = an,dis = ad;}
};
priority_queue<Point> q;
bool dij(ll start,ll maxf)
{
while(!q.empty()) q.pop();
memset(vis,0,sizeof(vis));
memset(dis,126,sizeof(dis));
if(cost[start] > maxf) return false;
dis[start] = 0;
q.push(Point(start,0));
int u;
while(!q.empty())
{
u = q.top().num;
q.pop();
if(vis[u]) continue;
vis[u] = 1;
for(int p = head[u];p;p=lines[p].next)
{
if(!vis[lines[p].to] \
&& cost[lines[p].to] <= maxf \
&& dis[lines[p].to] > dis[u] + lines[p].d)
{
dis[lines[p].to] = dis[u]+lines[p].d;
q.push(Point(lines[p].to,dis[lines[p].to]));
}
}
}
if(dis[v] > s) return false;
return true;
}
[JZOI]1251.收费站[二分][最短路]的更多相关文章
- Luogu P1951 收费站_NOI导刊2009提高(2) 二分 最短路
思路:二分+最短路 提交:1次 题解: 二分最后的答案. $ck()$: 对于每次的答案$md$跑$s,t$的最短路,但是不让$c[u]>md$的点去松弛别的边,即保证最短路不经过这个点.最后$ ...
- 二分+最短路 uvalive 3270 Simplified GSM Network(推荐)
// 二分+最短路 uvalive 3270 Simplified GSM Network(推荐) // 题意:已知B(1≤B≤50)个信号站和C(1≤C≤50)座城市的坐标,坐标的绝对值不大于100 ...
- BZOJ_1614_ [Usaco2007_Jan]_Telephone_Lines_架设电话线_(二分+最短路_Dijkstra/Spfa)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1614 分析 类似POJ_3662_Telephone_Lines_(二分+最短路) Dijks ...
- P1462 通往奥格瑞玛的道路 (二分+最短路)
题目 P1462 通往奥格瑞玛的道路 给定\(n\)个点\(m\)条边,每个点上都有点权\(f[i]\),每条边上有边权,找一条道路,使边权和小于给定的数\(b\),并使最大点权最小. 解析 二分一下 ...
- 二分+最短路 UVALive - 4223
题目链接:https://vjudge.net/contest/244167#problem/E 这题做了好久都还是超时,看了博客才发现可以用二分+最短路(dijkstra和spfa都可以),也可以用 ...
- 2018.07.20 bzoj1614: Telephone Lines架设电话线(二分+最短路)
传送门 这题直接做显然gg" role="presentation" style="position: relative;">gggg,看这数据 ...
- 2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018)- D. Delivery Delays -二分+最短路+枚举
2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018)- D. Delivery Delays -二分+最短路+枚举 ...
- BZOJ 1614 [Usaco2007 Jan]Telephone Lines架设电话线 (二分+最短路)
题意: 给一个2e4带正边权的图,可以免费k个边,一条路径的花费为路径上边权最大值,问你1到n的最小花费 思路: 对于一个x,我们如果将大于等于x的边权全部免费,那么至少需要免费的边的数量就是 “设大 ...
- Luogu P1462 通往奥格瑞玛的道路【二分/最短路】
题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡奥格瑞玛 题目描述 在艾泽拉斯, ...
随机推荐
- redis集群配置文件
bind xxx.xxx.xxx.xxx 绑定redis服务器网卡IP,默认为127.,即本地回环地址.这样的话,访问redis服务只能通过本机的客户端连接,而无法通过远程连接.如果bind选项为空的 ...
- Python 面试问答基础篇
1. Python是如何进行内存管理的? 答:从三个方面来说,一对象的引用计数机制,二垃圾回收机制,三内存池机制 一.对象的引用计数机制 Python内部使用引用计数,来保持追踪内存中的对 ...
- Python 之网络编程之socket(2)黏包现象和socketserver并发
一:黏包 ###tcp协议在发送数据时,会出现黏包现象. (1)数据粘包是因为在客户端/服务器端都会有一个数据缓冲区, 缓冲区用来临时保存数据,为了保证能够完整的接收到数据,因此缓冲区 ...
- redis 之redis集群与集群配置
一.为什么要用集群 redis3.0集群采用P2P模式,完全去中心化,将redis所有的key分成了16384个槽位,每个redis实例负责一部分slot,集群中的所有信息通过节点数据交换而更新. r ...
- java小项目之:抽奖系统!java初学者必备(内附源码)
[Java]Java摇奖源码,Java抽奖源码,Java随机抽奖源码 任务描述 本次任务要求为某商场开发一套幸运抽奖系统,客户必须首先注册成为该商场会员,会员登录成功后,就可以参加抽奖活动了.注册 用 ...
- C# 篇基础知识2——运算符、类型转换、流程控制、枚举、结构体和数组、函数
1.运算符.类型转换 计算某年y某月m某日d是周几的基姆拉尔森公式公式:int week = (d + 2*m + 3*(m + 1)/5 + y + y/4 - y/100 + y/400 + 1) ...
- Ecshop系统二次开发教程及流程演示
来源:互联网 作者:佚名 时间:03-01 16:05:31 [大 中 小] Ecshop想必大家不会觉得陌生吧,大部分的B2C独立网店系统都用的是Ecshop系统,很受用户的喜爱,但是由于Ecs ...
- NoSQL技术
NoSQL技术使用场景: 在我们日常的开发中,无不都是使用数据库来进行数据的存储,由于一般的系统任务中通常不会存在高并发的情况,所以这样看起来并没有什么问题,可是一旦涉及大数据量的需求,比如一些商品抢 ...
- No 'Access-Control-Allow-Origin'跨域问题- (mysql-thinkphp) (6)
因为ajax请求一个服务的时候,服务器端,比如thinkphp端,或者java框架,它会检测,你请求时候的域名,就是http请求的时候,request header不是会把客户端的Request UR ...
- docker中使用mongodb
连接mongodb容器,下拉alpine应用测试连接