GYM

来源:互联网 发布:36o安全卫士mac 编辑:程序博客网 时间:2024/05/21 09:48

Short Path
time limit per test
2.0 s
memory limit per test
256 MB
input
standard input
output
standard output

In my opinion, people are divided into two categories: some live in the future while others — in the past. Should it be explained what category did I belong? The mystery I hunted for a half of my life, finally was taking shape. Good Magician didn't know where Dragon hid. But he knew that bandit dens in some cities of the kingdom were controlled by people from the Dragon's gang. For each city he gave me a reliable information, whether Dragon controlled that city or not.

I was staring on the map of Fairy Kingdom trying to understand where to go now. There were n cities in the Kingdom, connected by mroads, with the length of the j-th road equal to wj. I guessed that Dragon hid in one of two cities controlled by his gang with the shortest path between them. First of all, the traffic of Blue Tea was the highest between them, and secondly, in case of emergency it was possible to move quickly from one of the cities to the other. All that remained was just to find such pair of cities.

Input

The first line contains two integers separated by a space: n and m (2 ≤ n ≤ 1051 ≤ m ≤ 105) — the number of cities in Fairy Kingdom and the number of roads between them, correspondingly.

The second line contains n integers separated by spaces. On the i-th position the number 1 is written, if the i-th city is under control of Dragon's gang; otherwise the number 0 is written there.

The next m lines contain three integers each, separated by spaces: aibiwi (1 ≤ ai < bi ≤ n1 ≤ wi ≤ 109) — the numbers of cities connected by a road and the length of this road. The cities are numbered from 1. Each pair of cities is presented at most once.

Output

In the first line output a single integer — the length of the shortest path between cities where Dragon presumably hides.

In the second line output two integers separated by a space — the numbers of these cities.

If there are several possible answers, output any of them. If no two cities controlled by Dragon's people have a path between them, output «No luck at all» without quotes.

Examples
input
4 41 0 0 11 2 11 3 22 4 33 4 1
output
34 1
input
7 91 0 1 1 0 0 11 2 51 4 1002 3 52 5 42 6 43 7 1004 5 26 7 25 6 3
output
74 7
input
2 10 01 2 1
output
No luck at all



题意:给你一张无向图,点分为0,1两种,求最近的两个1的距离,和他们的坐标。


解题思路:SPFA算法的思想很好的被应用了!做完这题对SPFA理解更加深刻了!思路是,先求出所有点,到他最近的1的距离。然后枚举所有的边,判断这条边的两边是什么类型的节点,分为三种情况讨论。如果都是1,直接更新答案。如果都是0,那么看看这两个0最近的1是不是同一个1,不是的话更新答案,一个0一个1的话,判断那个0最近的1是不是这个1,不是的话更新答案!所以这里的难点是怎么求所有点离他最近的1的距离……直接用SPFA松弛即可!


#include <iostream>#include <queue>#include <memory.h>using namespace std;typedef long long int ll;struct edge{    int v1;    int v2;    ll w;    int next;} e[1000005];int edge_num = 0;int head[1000005];void insert_edge(int v1, int v2, ll w){    e[edge_num].v1 = v1;    e[edge_num].v2 = v2;    e[edge_num].w = w;    e[edge_num].next = head[v1];    head[v1] = edge_num++;}int N, M;ll d[1000005];int type[1000005];int near[1000005];bool vis[1000005];void spfa(){    queue<int> que;    for (int i = 1; i <= N; i++)        if (!d[i])        {            que.push(i);            vis[i] = 1;        }    while (!que.empty())    {        int tp = que.front();        que.pop();        vis[tp] = 0;        for (int i = head[tp]; i!=-1; i = e[i].next)        {            int v2 = e[i].v2;            if (d[tp] + e[i].w < d[v2])            {                d[v2] = d[tp] + e[i].w;                near[v2] = near[tp];                if (!vis[v2])                {                    vis[v2] = 1;                    que.push(v2);                }            }        }    }}int main(){    scanf("%d%d", &N, &M);    for (int i = 1; i <= N; i++)    {        scanf("%d", &type[i]);        if (type[i])        {            d[i] = 0;            near[i] = i;        }        else            d[i] = 0x3f3f3f3f3f3f3f3f;    }    edge_num = 0;    memset(head, -1, sizeof(head));    int v1, v2;    ll w;    for (int i = 0; i < M; i++)    {        scanf("%d%d%lld", &v1, &v2, &w);        insert_edge(v1, v2, w);        insert_edge(v2, v1, w);    }    spfa();//    for(int i=1;i<=N;i++)//        cout<<near[i]<<endl;    ll ans = 0x3f3f3f3f3f3f3f3f;    for (int i = 0; i < edge_num; i++)    {        if (type[e[i].v1] == 1 && type[e[i].v2] == 1)        {            if (e[i].w < ans)            {                ans = e[i].w;                v1 = e[i].v1;                v2 = e[i].v2;            }        }        if (type[e[i].v1] == 0 && type[e[i].v2] == 1)        {            if (near[e[i].v1] != e[i].v2)                if (e[i].w + d[e[i].v1] < ans)                {                    ans = e[i].w + d[e[i].v1];                    v1 = near[e[i].v1];                    v2 = e[i].v2;                }        }        if (type[e[i].v1] == 1 && type[e[i].v2] == 0)        {            if (near[e[i].v2] != e[i].v1)                if (e[i].w + d[e[i].v2] < ans)                {                    ans = e[i].w + d[e[i].v2];                    v1 = e[i].v1;                    v2 = near[e[i].v2];                }        }        if (type[e[i].v1] == 0 && type[e[i].v2] == 0)        {            if (near[e[i].v2] != near[e[i].v1])                if (e[i].w + d[e[i].v1] + d[e[i].v2] < ans)                {                    ans = e[i].w + d[e[i].v1] + d[e[i].v2];                    v1 = near[e[i].v1];                    v2 = near[e[i].v2];                }        }    }    if (ans == 0x3f3f3f3f3f3f3f3f)    {        printf("No luck at all\n");    }    else    {        printf("%lld\n%d %d\n", ans, v1, v2);    }    return 0;}



原创粉丝点击