zoukankan      html  css  js  c++  java
  • 【洛谷习题】通往奥格瑞玛的道路

    题目的描述就很有意思,可以顺便去了解一下魔兽的背景故事。学习使我们快乐!

    题目链接:https://www.luogu.org/problemnew/show/P1462


    大清早上起来A掉一道题,好兴奋。看到题目要求收费最多的一次的最小值,想到用二分答案,二分这个最小值,然后去跑最短路,看是否可以,再不断更新区间,使这个值尽量小。几乎没有什么难点,但需要注意的细节有几个。估计答案的最大值应为收费最多的城市所收的费用;检验时,我是采用若发现某个结点的收费比当前所验证的答案大,则不再扩展,最后通过检查是否存在最短路,最短路是否可以回到奥格瑞玛,但问题是,如果终点不符合要求,同样会存在最短路,最短路可能也可以回到奥格瑞玛,所以还需要额外检查终点是否不超过检验的答案。

    还有,无向图用邻接表存储时,每条边会存两次!!!

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <queue>
     4 
     5 using namespace std;
     6 
     7 inline int get_num() {
     8     int num = 0;
     9     char c = getchar();
    10     while (c < '0' || c > '9') c = getchar();
    11     while (c >= '0' && c <= '9')
    12         num = num * 10 + c - '0', c = getchar();
    13     return num;
    14 }
    15 
    16 const int maxn = 1e4 + 5, maxm = 5e4 + 5, inf = 0x3f3f3f3f;
    17 
    18 int head[maxn], eid;
    19 
    20 struct Edge {
    21     int v, w, next;
    22 } edge[2 * maxm];
    23 
    24 inline void insert(int u, int v, int w) {
    25     edge[++eid].v = v;
    26     edge[eid].w = w;
    27     edge[eid].next = head[u];
    28     head[u] = eid;
    29 }
    30 
    31 struct node {
    32     int id, dist;
    33     node(int i, int d) : id(i), dist(d) {}
    34     bool operator < (const node& rhs) const {
    35         return dist > rhs.dist;
    36     }
    37 };
    38 
    39 int n, m, b, f[maxn], dist[maxn], vis[maxn];
    40 
    41 priority_queue<node> q;
    42 
    43 inline int check(int x) {
    44     memset(vis, 0, sizeof(vis));
    45     memset(dist, inf, sizeof(dist));
    46     dist[1] = 0;
    47     q.push(node(1, 0));
    48     while (!q.empty()) {
    49         int u = q.top().id;
    50         q.pop();
    51         if (vis[u]) continue;
    52         vis[u] = 1;
    53         for (int p = head[u]; p; p = edge[p].next) {
    54             int v = edge[p].v, w = edge[p].w;
    55             if (f[v] > x) continue;
    56             if (dist[v] > dist[u] + w) {
    57                 dist[v] = dist[u] + w;
    58                 q.push(node(v, dist[v]));
    59             }
    60         }
    61     }
    62     if (dist[n] > b) return 0;
    63     else return 1;
    64 }
    65 
    66 int main() {
    67     n = get_num(), m = get_num(), b = get_num();
    68     int mf = 0;
    69     for (int i = 1; i <= n; ++i) {
    70         f[i] = get_num();
    71         if (f[i] > mf) mf = f[i];
    72     }
    73     for (int i = 1; i <= m; ++i) {
    74         int u = get_num(), v = get_num(), w = get_num();
    75         insert(u, v, w);
    76         insert(v, u, w);
    77     }
    78     if (!check(mf)) {printf("AFK"); return 0;}
    79     int l = 1, r = mf;
    80     while (l < r) {
    81         int mid = l + (r - l) / 2;
    82         if (check(mid)) r = mid;
    83         else l = mid + 1;
    84     }
    85     printf("%d", l);
    86     return 0;
    87 }
    AC代码
  • 相关阅读:
    快排笔记C++
    security+redis+jwt 一个登陆注册查询的例子
    centeros 配置好环境虚拟机下载(java git mysql maven nginx Python redis nodejs tomcat )
    ZwQueryInformationProcess 反调试代码
    c++ 创建进程设置窗口标题模拟键盘鼠标例子
    求一个数二进制中包含多少个1
    憨批是我
    憨批是我
    问卷星实现自动填表刷问卷(问卷星分析post协议实现 安卓版)
    前端面试题 -- 综合
  • 原文地址:https://www.cnblogs.com/Mr94Kevin/p/9539894.html
Copyright © 2011-2022 走看看