查看原题请戳这里

核心思路

题目让求最大费用的最小值,很显然这道题可以二分,于是我们可以二分花费的最大值。

check函数

那么,我们该怎么写check函数呢?

我们可以删去费用大于mid的点以及与其相连的边,然后在剩余的点和边组成的图上跑一遍最短路求出从u到v需要消耗的最小的汽油,如果消耗汽油最小值不大于s,那么返回true,否则返回false。

注意事项

  1. 在二分时一定要判断到起点的花费是否大于mid
  2. r的初始值值应为$f_{max}+1$,因为如果$r_{start}=f_{max}$,那么$mid=(l+2)>>1$恒小于$f_{max}$,即你永远不会尝试取走花费最大的点。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#include<algorithm>
#define ll long long
#define INF 1000000000
#define re register using namespace std; long long ()
{
register long long x = 0,f = 1;register char ch;
ch = getchar();
while(ch > '9' || ch < '0'){if(ch == '-') f = -f;ch = getchar();}
while(ch <= '9' && ch >= '0'){x = x * 10 + ch - 48;ch = getchar();}
return x * f;
} long long n,m,u,v,s,ans,x,y,z,l,r,mid,cnt,flag,f[100005],d[100005],dis[100005],vis[100005]; struct 大专栏  题解 P1951 【收费站_NOI导刊2009提高(2)】s="title">edge{
long long to,nex,w;
}e[1000005]; struct node{
long long k,dis;
bool operator < (const node &x) const{return x.dis < dis;}
}; void add(long long x,long long y,long long z)
{
e[++cnt].to = y;
e[cnt].nex = d[x];
e[cnt].w = z;
d[x] = cnt;
} priority_queue<node> que; void dij()
{
while(!que.empty()) que.pop();
que.push((node){u,0});
while(!que.empty())
{
node u = que.top();
que.pop();
if(vis[u.k]) continue;
vis[u.k] = 1;
if(f[u.k] > mid) continue;
for(register int i = d[u.k]; i; i = e[i].nex)
{
if(f[e[i].to] > mid) continue;
if(dis[e[i].to] > dis[u.k] + e[i].w)
{
dis[e[i].to] = e[i].w + dis[u.k];
if(!vis[e[i].to]) que.push((node){e[i].to,dis[e[i].to]});
}
}
}
} bool check(long long Max)
{
if(f[u] > Max || f[v] > Max) return false;
memset(dis,0x7f,sizeof(dis));
memset(vis,0,sizeof(vis));
dis[u] = 0;
dij();
if(dis[v] <= s) flag = 1;
if(dis[v] <= s) return true;
return false;
} struct EDGE{
long long x,y,z;
}E[1000005]; bool cmp(EDGE a, EDGE b)
{
if(a.x != b.x) return a.x < b.x;
if(a.y != b.y) return a.y < b.y;
return a.z < b.z;
} int main()
{
n = read(); m = read(); u = read(); v = read(); s = read();
for(int i = 1; i <= n; i++) f[i] = read(),r = max(r,f[i]);
r++;
for(int i = 1; i <= m; i++)
{
E[i].x = read();
E[i].y = read();
E[i].z = read();
}
sort(E + 1, E + m + 1, cmp);
for(int i = 1; i <= m; i++)
if((E[i].x != E[i - 1].x || E[i].y != E[i - 1].y) && E[i].x != E[i].y)
add(E[i].x,E[i].y,E[i].z),add(E[i].y,E[i].x,E[i].z);
while(l < r)
{
mid = (l + r) >> 1;
if(check(mid)) r = mid;
else l = mid + 1;
}
if(flag == 0) printf("-1n");
else printf("%lldn",r);
return 0;
}

题解 P1951 【收费站_NOI导刊2009提高(2)】的更多相关文章

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

    目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例: 输出样例: 说明 思路 AC代码 总结 题面 题目链接 P1951 收费站_NOI导刊2009提高(2) 其 ...

  2. [洛谷P1951]收费站_NOI导刊2009提高(2)

    题目大意:有一张$n$个点$m$条边的图,每个点有一个权值$w_i$,有边权,询问从$S$到$T$的路径中,边权和小于$s$,且$\max\limits_{路径经过k}\{w_i\}$最小,输出这个最 ...

  3. 洛谷 P1951 收费站_NOI导刊2009提高(2)

    题目描述 在某个遥远的国家里,有n个城市.编号为1,2,3,…,n. 这个国家的政府修建了m条双向的公路.每条公路连接着两个城市.沿着某条公路,开车从一个城市到另一个城市,需要花费一定的汽油. 开车每 ...

  4. 洛谷——P1951 收费站_NOI导刊2009提高(2)

    https://www.luogu.org/problem/show?pid=1951 题目描述 在某个遥远的国家里,有n个城市.编号为1,2,3,…,n. 这个国家的政府修建了m条双向的公路.每条公 ...

  5. luogu P1951 收费站_NOI导刊2009提高(2) |二分答案+最短路

    题目描述 在某个遥远的国家里,有n个城市.编号为1,2,3,-,n. 这个国家的政府修建了m条双向的公路.每条公路连接着两个城市.沿着某条公路,开车从一个城市到另一个城市,需要花费一定的汽油. 开车每 ...

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

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

  7. Luogu P1951 收费站_NOI导刊2009提高(2)

    二分答案+堆优Dijkstra 这个题有些巧妙. 首先,因为要在油量耗完之前跑到终点,所以我们可以用最短路.只要从\(s\)出发到\(t\),它的最短距离大于油量,我们就可以断定它一定走不通,直接输出 ...

  8. 洛谷1462(重题1951) 通往奥格瑞玛的道路(收费站_NOI导刊2009提高(2))

    1462原题链接 1951原题链接 显然答案有单调性,所以可以二分答案,用\(SPFA\)或\(dijkstra\)跑最短路来判断是否可行即可. 注意起点也要收费,\(1462\)数据较水,我一开始没 ...

  9. 洛谷 P1950 长方形_NOI导刊2009提高(2) 题解

    P1950 长方形_NOI导刊2009提高(2) 题目描述 小明今天突发奇想,想从一张用过的纸中剪出一个长方形. 为了简化问题,小明做出如下规定: (1)这张纸的长宽分别为n,m.小明讲这张纸看成是由 ...

随机推荐

  1. int a;和 int &a;的区别

    int a的意思是定义一个变量a int &a意思是定义一个引用 //引用相当于指针再取值 他和被引用的变量都是表示同一块内存 引用就是给变量取别名 int b ;int &a=b; ...

  2. php获取客户IP

    获取客户真实IP,保存到数据库建议转整 function getIp(){ $ip = ''; if(!empty($_SERVER['HTTP_CLIENT_IP'])){ $ip = $_SERV ...

  3. flutter 命令卡主的问题

    情况 1 镜像的问题 如果你的镜像已经设置,却仍然卡主,那么请参考情况 2 这种情况在中文官网上已经有了,并且有这修改镜像的方法,附上链接: https://flutter.cn/community/ ...

  4. Spring Test+JUnit4整合使用测试ZZJ_淘淘商城项目:day01(RESTful Web Service)

    针对整合的Dao层与Service层,在做spring与通用Mapper和分页插件相关测试时比较麻烦.如果只用JUnit测试,需要每次Test方法里初始化一下applicationContext,效率 ...

  5. tesseract系列(4) -- tesseract训练问题总结

    1. 每次训练模型删除目录下,上述重复的名字 2. 生成inttemp.pffmtable文件的时候,如果下述命令(1)不行的话,或者报错,使用命令(2) (1)mftraining -F font_ ...

  6. usb转串口驱动安装失败

    方法一:通过驱动精灵安装 方法二:手动下载后安装,下载地址如下http://www.wch.cn/download/CH341SER_EXE.html https://blog.csdn.net/ja ...

  7. Linux虚拟机添加硬盘

    任务:添加1块硬盘,并且分1个区,挂载到/bak 第一.插上硬盘 第二.分区 第三.格式化(定义:文件系统的类型)  FAT,FAT32,NTFS,ext1,ext2,ext3,ext4,.... 第 ...

  8. 吴裕雄--天生自然 JAVA开发学习:序列化

    public final void writeObject(Object x) throws IOException public final Object readObject() throws I ...

  9. 用原生socket发送HTTP数据包

    分享一个写扫描器和POC时的小技巧. 有时候有的漏洞需要一些特殊的数据包,比如说畸形的HTTP头.畸形的Multipart.畸形的chunk包等,此时用编程语言自己的HTTP库可能构造不出这种数据包, ...

  10. AI动作捕捉技术,会让制造业大幅度降低成本吗?

    现代动作捕捉系统应该是起源于100多年前的动画工业,通过一种叫做"动态遮罩或影像描摹"的技术,动画师们可以获得流畅的.栩栩如生的动作:后来到了20世纪80年代,动画师们设计出带有活 ...