• 洛谷 P1462 通往奥格瑞玛的道路


    Description

    在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量

    有一天他醒来后发现自己居然到了联盟的主城暴风城

    在被众多联盟的士兵攻击后,他决定逃回自己的家乡奥格瑞玛

    在艾泽拉斯,有n个城市。编号为1,2,3,...,n。

    城市之间有m条双向的公路,连接着两个城市,从某个城市到另一个城市,会遭到联盟的攻击,进而损失一定的血量。

    每次经过一个城市,都会被收取一定的过路费(包括起点和终点)。路上并没有收费站。

    假设1为暴风城,n为奥格瑞玛,而他的血量最多为b,出发时他的血量是满的。

    歪嘴哦不希望花很多钱,他想知道,在可以到达奥格瑞玛的情况下,他所经过的所有城市中最多的一次收取的费用的最小值是多少。

    Input

    第一行3个正整数,n,m,b。分别表示有n个城市,m条公路,歪嘴哦的血量为b。

    接下来有n行,每行1个正整数,fi。表示经过城市i,需要交费fi元。

    再接下来有m行,每行3个正整数,ai,bi,ci(1<=ai,bi<=n)。表示城市ai和城市bi之间有一条公路,如果从城市ai到城市bi,或者从城市bi到城市ai,会损失ci的血量。

    Output 

    仅一个整数,表示歪嘴哦交费最多的一次的最小值。

    如果他无法到达奥格瑞玛,输出AFK。

    Sample Input

    4 4 8

    8

    5

    6

    10

    2 1 2

    2 4 1

    1 3 4

    3 4 3

    Sample Output

    10

    Hint

    对于60%的数据,满足n≤200,m≤10000,b≤200

    对于100%的数据,满足n≤10000,m≤50000,b≤1000000000

    对于100%的数据,满足ci≤1000000000,fi≤1000000000,可能有两条边连接着相同的城市。


    思路显然:二分 + 最短路,注意数据范围(被long long坑了...dis数组会爆);

    代码:

     1 /*
     2 二分 + 最短路
     3 */
     4 #include<iostream>
     5 #include<cstdio>
     6 #include<cstring>
     7 #include<queue>
     8 typedef long long ll;
     9 
    10 const int maxn = 10000 + 5;
    11 const int maxm = 50000 + 5;//双向
    12 struct Edge
    13 {
    14     int f, t, v;
    15 }gra[maxm << 1];
    16 int n, m, heal, u, arr[maxn];
    17 int fir[maxn], nxt[maxm << 1];
    18 ll dis[maxn];
    19 bool used[maxn];
    20 std::queue<int>Q;
    21 void Build(int, int, int);
    22 bool Check(int);
    23 
    24 int main()
    25 {
    26     memset(fir, -1, sizeof(fir));
    27     scanf("%d%d%d", &n, &m, &heal);
    28     int l = 1e9 + 7, r = -1;
    29     for(int i = 1; i <= n; i++)
    30         scanf("%d", &arr[i]),
    31         l = std::min(l, arr[i]), r = std::max(r, arr[i]);
    32     for(int i = 1; i <= m; i++)
    33     {
    34         int f, t, v;
    35         scanf("%d%d%d", &f, &t, &v);
    36         Build(f, t, v);
    37     }
    38     bool f = 0;
    39     while(l <= r)
    40     {
    41         int mid = l + r >> 1;
    42         if(Check(mid)) r = mid - 1, f = 1;
    43         else l = mid + 1;
    44     }
    45     if(!f) puts("AFK");
    46     else std::cout << r + 1;
    47     return 0;
    48 }
    49 
    50 bool Check(int ans)
    51 {
    52     if(arr[1] > ans||arr[n] > ans) return 0;
    53     memset(dis, 0x7f, sizeof(dis));
    54     dis[1] = 0;
    55     Q.push(1);
    56     while(!Q.empty())
    57     {
    58         int k = Q.front();
    59         Q.pop();
    60         used[k] = 0;
    61         for(int i = fir[k]; ~i; i = nxt[i])
    62         {
    63             int tmp = gra[i].t;
    64             if(arr[tmp] > ans) continue;
    65             if(dis[tmp] > dis[k] + (ll)gra[i].v)
    66             {
    67                 dis[tmp] = dis[k] + (ll)gra[i].v;
    68                 if(used[tmp]) continue;
    69                 used[tmp] = 1;
    70                 Q.push(tmp);
    71             }
    72         }
    73     }
    74     if(dis[n] >= (ll)heal) return 0;
    75     return 1;
    76 }
    77 
    78 void Build(int f, int t, int v)
    79 {
    80     gra[++u] = (Edge){f, t, v};
    81     nxt[u] = fir[f], fir[f] = u;
    82     gra[++u] = (Edge){t, f, v};
    83     nxt[u] = fir[t], fir[t] = u;
    84 }
  • 相关阅读:
    windows 7系统搭建PHP网站环境
    本机搭建PHP环境全教程(图文)
    cmd不是内部命令解决方法
    [Tex学习笔记]章节用罗马字母编号
    丁伟岳院士逝世 享年70岁
    2014年度江西省青年科学家培养对象名单(共36名)
    Alexander Grothendieck去世了
    [詹兴致矩阵论习题参考解答]序言
    2014-2015第一学期听课安排
    一个老和尚的真言
  • 原文地址:https://www.cnblogs.com/DreifxP/p/7804655.html
Copyright © 2020-2023  润新知