首页 > 代码库 > luogu P1462 通往奥格瑞玛的道路

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;
}

 

luogu P1462 通往奥格瑞玛的道路