luogu P1462 通往奥格瑞玛的道路

二次联通门 : luogu P1462 通往奥格瑞玛的道路

/*
    luogu P1462 通往奥格瑞玛的道路

        二分答案 + 最短路 

        二分最大钱数

        每次只走小于当前钱数的路
        若最后的血量可以
        则证明答案可行
        就继续二分
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#define Max 10005
#define INF 1e7

using namespace std;

inline int max (int a, int b)
{
    return a > b ? a : b;
}

inline int min (int a, int b)
{
    return a < b ? a : b;
}

void read (int &now)
{
    now = 0;
    char word = getchar ();
    while (word > ‘9‘ || word < ‘0‘)
        word = getchar ();
    while (word >= ‘0‘ && word <= ‘9‘)
    {
        now = now * 10 + word - ‘0‘;
        word = getchar ();
    }
}

struct Edge
{
    int to;
    int dis;
    int next;
}edge[Max * 10];

int edge_list[Max];
int Edge_Count;
int dis[Max];
int N, M;
bool visit[Max];
int cost[Max];
int Blood;        

inline void AddEdge (int from, int to, int dis)
{
    Edge_Count++;
    edge[Edge_Count].to = to;
    edge[Edge_Count].dis = dis;
    edge[Edge_Count].next = edge_list[from];
    edge_list[from] = Edge_Count;
}

bool Check (int Money)
{
    if (Money < cost[1])
        return false;
    queue <int> Queue;
    for (int i = 1; i <= N + 5; i++)
    {
        visit[i] = false;
        dis[i] = INF;
    }
    visit[1] = true;
    dis[1] = 0;
    Queue.push (1);
    int now;
    while (!Queue.empty())
    {
        now = Queue.front ();
        Queue.pop ();
        visit[now] = false;
        for (int i = edge_list[now]; i; i = edge[i].next)
            if (cost[edge[i].to] <= Money && dis[edge[i].to] > edge[i].dis + dis[now])
            {
                dis[edge[i].to] = edge[i].dis + dis[now];
                if (!visit[edge[i].to])
                {
                    Queue.push (edge[i].to);
                    visit[edge[i].to] = true;
                }
            }
    }
    if (dis[N] <= Blood)
        return true;
    else
        return false;
}

int main (int argc, char *argv[])
{

    read (N);
    read (M);
    read (Blood);

    int l = INF, r = 0;

    for (int i = 1; i <= N; i++)
    {
        read (cost[i]);
        l = min (l, cost[i]);
        r = max (r, cost[i]);
    }
    int u, v, x;

    for (int i = 1; i <= M; i++)
    {
        read (u);
        read (v);
        read (x);

        AddEdge (u, v, x);
        AddEdge (v, u, x);
    }
    int Mid;
    int Answer;
    while (l <= r)
    {
        Mid = (l + r) >> 1;
        if (Check (Mid))
        {
            r = Mid - 1;
            Answer = Mid;
        }
        else
            l = Mid + 1;
    }
    if (Answer)
        printf ("%d", Answer);
    else
        printf ("AFK");
    return 0;
}
时间: 2024-10-22 02:15:07

luogu P1462 通往奥格瑞玛的道路的相关文章

[Luogu P1462] 通往奥格瑞玛的道路 (二分答案+最短路径)

题面 传送门:https://www.luogu.org/problemnew/show/P1462 Solution 这道题如果去除掉经过城市的收费.那么就是裸的最短路 但是题目要求经过城市中最多的一次性收费的最小值,也就是说让经过的最大值尽可能小 那我们可以考虑二分这个最大值 一切收费大于我们二分的值的城市统统不走 在最短路那里改一下就好了 然后就OjbK了 时间复杂度 O(n*logn*log b) Code //Luogu P1462 通往奥格瑞玛的道路 //May,27th,2018

【luogu P1462 通往奥格瑞玛的道路】 题解

题目链接:https://www.luogu.org/problemnew/show/P1462 记住HP=0也叫死. #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 5000001; const int inf = 0x7f; l

洛谷P1462 通往奥格瑞玛的道路 二分答案+最短路SPFA

洛谷P1462 通往奥格瑞玛的道路二分答案+最短路SPFA 二分交费最多的一次的钱数 然后只将符合要求的边加入图中 如果到终点的最短路大于等于血量 或者直接起点不能到达终点那么说明不符合要求 需要加大答案 时间复杂度 (log答案)* Ek 需要注意如果本来就不能到达 那么直接输出AFK 1 #include <bits/stdc++.h> 2 #define LL long long 3 #define For(i,j,k) for(int i=j;i<=k;i++) 4 using

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

P1462 通往奥格瑞玛的道路 219通过 1.2K提交 题目提供者gconeice 标签二分图论洛谷原创 难度提高+/省选- 提交该题 讨论 题解 记录 最新讨论 RE好多.. 到底怎么判断AFK啊 看不懂题目.. 建议修改题目 究竟是血量为负算挂还是生命… 题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡奥格瑞玛 题目描述 在艾泽拉斯,有n个城市.编号为1,2,3,...,

P1462 通往奥格瑞玛的道路 (二分+最短路)

题目 P1462 通往奥格瑞玛的道路 给定\(n\)个点\(m\)条边,每个点上都有点权\(f[i]\),每条边上有边权,找一条道路,使边权和小于给定的数\(b\),并使最大点权最小. 解析 二分一下钱,然后跑最短路,判断一下如果只有这么多钱的话能不能到终点(最短路边权和是不是不超过\(b\)),套个最短路板子,套个二分板子,没了. 代码 //二分+最短路 #include <bits/stdc++.h> using namespace std; const int N = 1e5 + 10;

【洛谷】【二分答案+最短路】P1462 通往奥格瑞玛的道路

在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡奥格瑞玛 题目背景 [题目描述:] 在艾泽拉斯,有n个城市.编号为1,2,3,...,n. 城市之间有m条双向的公路,连接着两个城市,从某个城市到另一个城市,会遭到联盟的攻击,进而损失一定的血量. 每次经过一个城市,都会被收取一定的过路费(包括起点和终点).路上并没有收费站. 假设1为暴风城,n为奥格瑞玛,而他的血量最多为b,出发时他的血量

洛谷 P1462 通往奥格瑞玛的道路(spfa+二分搜索)(4boy)

原题:http://www.luogu.org/problem/show?pid=1462#sub 4boy: 大意:给出n个城市,有m条路,每经过一个城市都要交钱,每经过一条道路都要扣HP,有HP上限:要从1走到n, 求在HP没扣完的情况下,从1到n经过城市的最大花费的最小值. 思路:用二分搜索cost的值的最小值,用spfa搜索从1到n所需的最少HP,在spfa中判断cost[i]与x详见代码注释: 1 #include<iostream> 2 #include<cstring>

洛谷P1462通往奥格瑞玛的道路——二分答案最短路

题目:https://www.luogu.org/problemnew/show/P1462 最大值最小问题,二分答案. 代码如下: #include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; int const MAXN=1e5+5; queue<int>q; int n,m,b,cost[MAXN],head[MAXN],

洛谷P1462 通往奥格瑞玛的道路[二分答案 spfa 离散化]

题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡奥格瑞玛 题目描述 在艾泽拉斯,有n个城市.编号为1,2,3,...,n. 城市之间有m条双向的公路,连接着两个城市,从某个城市到另一个城市,会遭到联盟的攻击,进而损失一定的血量. 没经过一个城市,都会被收取一定的过路费(包括起点和终点).路上并没有收费站. 假设1为暴风城,n为奥格瑞玛,而他的血量最多为b,出发时他的血量是满的.