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]的区间内。

因此我们二分枚举答案检验是否合法:

  1. //二分答案
  2. ll ll = 1,rr = maxfee,ans = -1,mid;
  3. while(ll<=rr)
  4. {
  5. mid = (ll+rr)>>1;
  6. if(dij(u,mid))//检验是否合法
  7. {
  8. ans = mid;
  9. rr = mid-1;
  10. }
  11. else
  12. ll = mid+1;
  13. }

二分后使用最短路算法,更新的时候判断 目标点 的点权是否合法,若不合法则不能用于更新最短路。

那么我们需要对更新的判断语句做一点调整。

dijkstra算法为例进行对比:

  1. if(!vis[v] && dis[v] > dis[u] + map[u][v])//以基点更新最短路
  2. dis[v] = dis[u] + map[u][v];//这里使用了简朴的写法,仅仅用于对比

那么我们添加限定条件后,只是简单地变为

  1. if(!vis[v] && cost[v] <= ans && dis[v] > dis[u] + map[u][v])
  2. dis[v] = dis[u] + map[u][v];

这个ans即我们正在验证的答案。最后求完最短路,判定答案是否合法就简单了:

  1. if(dis[v] > s) return false;

因为dis数组初始化为无穷大,所以无论是未访问到的情况还是超过给出最短路限定长度s的情况都能这样排掉。

到此,本题就结束了。

但其实,还有最后一个点,卡了我几十分钟的一个神奇问题(当然是我太菜了)

还需要判断起点的点权是否合法(捂脸)

  1. if(cost[start] > maxf) return false;

就这么一行……

Code

  • 链式前向星存图
  • 根优化dijkstra求最短路
  • 二分查找答案
  1. #include <cstdio>
  2. #include <cstring>
  3. #include <queue>
  4. typedef long long ll;
  5. using namespace std;
  6. //functions
  7. inline void add(const ll&,const ll&,const ll&);
  8. void read(ll&);
  9. ll init();
  10. bool dij(ll,ll);
  11. //end
  12. struct node
  13. {
  14. ll d,to,next;
  15. node(ll q,ll w,ll e)
  16. {to=q,next=w,d=e;}
  17. node(){}
  18. }lines[100010];
  19. ll head[10010];
  20. ll cost[10010];
  21. ll dis[10010];
  22. ll n,m,u,v,s;
  23. int main()
  24. {
  25. ll maxfee = init();//初始化
  26. //二分答案
  27. ll ll = 1,rr = maxfee,ans = -1,mid;
  28. while(ll<=rr)
  29. {
  30. mid = (ll+rr)>>1;
  31. if(dij(u,mid))
  32. {
  33. ans = mid;
  34. rr = mid-1;
  35. }
  36. else
  37. ll = mid+1;
  38. }
  39. printf("%d",ans);
  40. return 0;
  41. }
  42. ll init()
  43. {
  44. read(n);read(m);read(u);read(v);read(s);
  45. ll maxfee = 0;
  46. for(int i = 1;i<=n;++i)
  47. {
  48. read(cost[i]);
  49. if(cost[i] > maxfee)
  50. maxfee = cost[i];
  51. }
  52. ll ai,bi,ci;
  53. for(int i = 1;i<=m;++i)
  54. {
  55. read(ai);
  56. read(bi);
  57. read(ci);
  58. add(ai,bi,ci);
  59. add(bi,ai,ci);
  60. }
  61. return maxfee;
  62. }
  63. void read(ll &r)
  64. {
  65. static char c;r = 0;
  66. for(c=getchar();c>'9'||c<'0';c=getchar());
  67. for(;c>='0'&&c<='9';r=(r<<1)+(r<<3)+c-48,c=getchar());
  68. }
  69. inline void add(const ll &x,const ll &y,const ll &d)
  70. {
  71. static ll tot = 0;
  72. lines[++tot] = node(y,head[x],d);
  73. head[x] = tot;
  74. }
  75. ll vis[10010];
  76. struct Point
  77. {
  78. ll num,dis;
  79. bool operator<(const Point &b) const
  80. {
  81. return dis>b.dis;
  82. }
  83. Point(){}
  84. Point(ll an,ll ad){num = an,dis = ad;}
  85. };
  86. priority_queue<Point> q;
  87. bool dij(ll start,ll maxf)
  88. {
  89. while(!q.empty()) q.pop();
  90. memset(vis,0,sizeof(vis));
  91. memset(dis,126,sizeof(dis));
  92. if(cost[start] > maxf) return false;
  93. dis[start] = 0;
  94. q.push(Point(start,0));
  95. int u;
  96. while(!q.empty())
  97. {
  98. u = q.top().num;
  99. q.pop();
  100. if(vis[u]) continue;
  101. vis[u] = 1;
  102. for(int p = head[u];p;p=lines[p].next)
  103. {
  104. if(!vis[lines[p].to] \
  105. && cost[lines[p].to] <= maxf \
  106. && dis[lines[p].to] > dis[u] + lines[p].d)
  107. {
  108. dis[lines[p].to] = dis[u]+lines[p].d;
  109. q.push(Point(lines[p].to,dis[lines[p].to]));
  110. }
  111. }
  112. }
  113. if(dis[v] > s) return false;
  114. return true;
  115. }

[JZOI]1251.收费站[二分][最短路]的更多相关文章

  1. Luogu P1951 收费站_NOI导刊2009提高(2) 二分 最短路

    思路:二分+最短路 提交:1次 题解: 二分最后的答案. $ck()$: 对于每次的答案$md$跑$s,t$的最短路,但是不让$c[u]>md$的点去松弛别的边,即保证最短路不经过这个点.最后$ ...

  2. 二分+最短路 uvalive 3270 Simplified GSM Network(推荐)

    // 二分+最短路 uvalive 3270 Simplified GSM Network(推荐) // 题意:已知B(1≤B≤50)个信号站和C(1≤C≤50)座城市的坐标,坐标的绝对值不大于100 ...

  3. BZOJ_1614_ [Usaco2007_Jan]_Telephone_Lines_架设电话线_(二分+最短路_Dijkstra/Spfa)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1614 分析 类似POJ_3662_Telephone_Lines_(二分+最短路) Dijks ...

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

    题目 P1462 通往奥格瑞玛的道路 给定\(n\)个点\(m\)条边,每个点上都有点权\(f[i]\),每条边上有边权,找一条道路,使边权和小于给定的数\(b\),并使最大点权最小. 解析 二分一下 ...

  5. 二分+最短路 UVALive - 4223

    题目链接:https://vjudge.net/contest/244167#problem/E 这题做了好久都还是超时,看了博客才发现可以用二分+最短路(dijkstra和spfa都可以),也可以用 ...

  6. 2018.07.20 bzoj1614: Telephone Lines架设电话线(二分+最短路)

    传送门 这题直接做显然gg" role="presentation" style="position: relative;">gggg,看这数据 ...

  7. 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 -二分+最短路+枚举 ...

  8. BZOJ 1614 [Usaco2007 Jan]Telephone Lines架设电话线 (二分+最短路)

    题意: 给一个2e4带正边权的图,可以免费k个边,一条路径的花费为路径上边权最大值,问你1到n的最小花费 思路: 对于一个x,我们如果将大于等于x的边权全部免费,那么至少需要免费的边的数量就是 “设大 ...

  9. Luogu P1462 通往奥格瑞玛的道路【二分/最短路】

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

随机推荐

  1. Django 学习 之 模板(html)与配置静态文件

     一.模板(html) 1.模板语法之变量:语法为 {{ }} 在 Django 模板中遍历复杂数据结构的关键是句点字符, 语法:{{ var_name }} var_name 是一个变量名称,需要和 ...

  2. Java最新面试题

    本人免费整理了Java高级资料,涵盖了Java.Redis.MongoDB.MySQL.Zookeeper.Spring Cloud.Dubbo高并发分布式等教程,一共30G,需要自己领取.传送门:h ...

  3. 本周总结(19年暑假)—— Part1

    日期:2019.7.14 博客期:107 星期日 这几周正在摸索着找寻与大型数据库相关的知识,重装了电脑,配置了虚拟机的环境,继续研究了几下修改器.

  4. kd-tree理论以及在PCL 中的代码的实现(转载)

    该文转自:https://www.cnblogs.com/li-yao7758258/p/6437440.html kd-tree理论以及在PCL 中的代码的实现   (小技巧记录:博客园编辑的网页界 ...

  5. struts2--验证器

    1.输入验证: --struts2提供了一些基于Xwork Validation Framework的内建验证程序,使用这些验证程序不需要变编程,只要在一个XML文件里进行声明,声明的内容如下: &g ...

  6. 30 整数中1出现的次数(从1到n整数中1出现的次数)这题很难要多看*

    题目描述 求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1.10.11.12.13因此共出现6次,但是对于后面问题他就没辙了. ...

  7. question1 赋值运算操作符

    注意的问题书上讲的很详细了 下面是代码实现,但是VS有一个问题,strcpy安全性较低,虽然可以通脱编译,但是运行会报错,提示用strcpy_s()替代,但是,这里用strcpy()替代也不行, // ...

  8. Time Series_1_BRKA Case

    Berkshire Hathaway (The most expensive stock ever in the world) 1.1 Download data require(quantmod) ...

  9. 多实例mysql的安装和管理

    多实例mysql的安装和管理 http://blog.chinaunix.net/uid-20639775-id-3438560.html mysql的多实例有两种方式可以实现,两种方式各有利弊.第一 ...

  10. centos 6.5安装NodeJS

    centos 6.5安装NodeJS 下载 可以在本地下载node.js最新版,然后通过ftp工具上传到服务器,或者直接在服务器终端使用wget命令下载(我当时下载的是node-v7.5.0-linu ...