查看原题请戳这里

核心思路

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

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. Est数据库

    Est--编码序列,gene 片段且具有标签 其中,est数据库中是类似测序1.测序2.测序3这样的序列.实验室测得的序列是cDNA,通过上图方法拼接,电脑克隆(dbest).如果有overlap则认 ...

  2. Comet OJ - Contest #3 D可爱的菜菜子(线段树+线性基的合并)

    这题其实挺经典的,看到求异或最大,显然想到的是线性基,不过这怎么维护?当然区间有关的东西都可以上线段树,区间修改时记录每个点的修改量k,然后合并线性基时再加入线性基.因为线性基是求一组极大线性无关组, ...

  3. Python - 文件和目录

    # -*- coding: utf-8 -*- import os print(os.name) # 获取操作系统类型 # print(os.uname()) # 获取操作系统的详细信息,Win不支持 ...

  4. 从list中取N个随机生成一个集合

    在工作中发现有很多有序算法,较少见到一些可用的无序随机算法.无序随机算法的目的是让客户感觉每次都不一样,因为一直看一样的会审美疲劳哈. 在jdk自带一种CollectionUtils.shuffle& ...

  5. ElasticSearch 本机可以访问,外网无法访问----问题解决

    问题:本机可以访问,外网无法访问 config/elasticsearch.yml network.host: 0.0.0.0 使用普通用户zuoys,重启es,报错如下: [1]: max file ...

  6. 通过java语言实现MD5加密

    通过java语言实现MD5加密public static String getMd5(String str) { try { MessageDigest md5 = MessageDigest.get ...

  7. redis簡單命令

  8. kubectl 命令详解

    使用kubectl来管理Kubernetes集群. kubectl命令的选项: 选项 作用 --alsologtostderr[=false] 同时输出日志到标准错误控制台和文件 --api-vers ...

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

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

  10. built?

    题目描述 There are N towns on a plane. The i-th town is located at the coordinates (xi,yi). There may be ...