查看原题请戳这里

核心思路

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

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. 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
  1. #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    #define ll long long
    #define INF 1000000000
    #define re register
  2.  
  3. using namespace std;
  4.  
  5. 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;
    }
  6.  
  7. long long n,m,u,v,s,ans,x,y,z,l,r,mid,cnt,flag,f[100005],d[100005],dis[100005],vis[100005];
  8.  
  9. struct 大专栏  题解 P1951 【收费站_NOI导刊2009提高(2)】s="title">edge{
    long long to,nex,w;
    }e[1000005];
  10.  
  11. struct node{
    long long k,dis;
    bool operator < (const node &x) const{return x.dis < dis;}
    };
  12.  
  13. 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;
    }
  14.  
  15. priority_queue<node> que;
  16.  
  17. 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]});
    }
    }
    }
    }
  18.  
  19. 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;
    }
  20.  
  21. struct EDGE{
    long long x,y,z;
    }E[1000005];
  22.  
  23. 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;
    }
  24.  
  25. 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. Oracle连接Navicat Premium遇到的问题

      ORA-28040: 没有匹配的验证协议. 通过查找资料找到了好的解决方案.可以不需要到官网上下载新的驱动来解决问题.    方法:在Oracle的安装路径下找到sqlnet.ora文件.(我的安 ...

  2. ios uiimagepickercontroller 选择相册或者拍照上传

    首先需要实现UIImagePickerControllerDelegate 代理 实现其imagePickerController 方法  这里用于选择图片或的拍照回调 //调用相机拍照 或者 图库选 ...

  3. python3拆包详解

    对于可迭代对象,如元组.列表.字符串.集合.字典这些可迭代对象都可以被拆包,拆包是指将一个结构中的数据拆分为多个单独变量中.拆包的方式大致有两种,一种是以变量的方式来接收,另一种是用'*'号.下面先讲 ...

  4. CodeForces 1005D Polycarp and Div 3(思维、贪心、dp)

    http://codeforces.com/problemset/problem/1005/D  题意: 给一个仅包含数字的字符串,将字符串分割成多个片段(无前导0),求这些片段里最多有多少是3的倍数 ...

  5. Patroni 修改配置

    Patroni 修改配置 背景 使用 Patroni 部署 postgresql 集群的时候,不能单独修改单点的配置,这里需要通过 Patroni 来修改配置. 修改步骤 1. 修改 postgres ...

  6. mysql之存储过程(三)

    带参数的存储过程: 特别说明: 在游标中是不支持对形参的判断的,外部可以 调用操作: call settlexxxxx_common("1970-11",999); 定义如下:   ...

  7. std::string和ctime之间的转换

    int year, month, day, hour, minute, second; string strTime: sscanf(strTime.c_str(), "%d-%d-%d % ...

  8. EternalBlue永恒之蓝漏洞复现

    EternalBlue漏洞复现 1.    实训目的 永恒之蓝(EternalBlue)是由美国国家安全局开发的漏洞利用程序,对应微软漏洞编号ms17-010.该漏洞利用工具由一个名为”影子经济人”( ...

  9. shiro PermissionUtil

    package org.linlinjava.litemall.admin.util; import org.apache.shiro.authz.annotation.RequiresPermiss ...

  10. aclocal-1.13: command not found

    原因: 将编译好的工程拷贝到系统版本不一样的系统中,再进行编译会出现此类问题. 解决方法: yum install automake autoconf yum install libtool auto ...