1. 程式人生 > >codevs 1269 匈牙利遊戲

codevs 1269 匈牙利遊戲

out use ccf default sta row target const des

        codevs 1269 匈牙利遊戲

題目描述 Description

Welcome to the Hungary Games! The streets of Budapest form a twisted network of one-way streets.

歡迎來到匈牙利遊戲!布達佩斯(匈牙利首都)的街道形成了一個彎曲的單向網絡。

You have been forced to join a race as part of a “Reality TV” show where you race through these streets, starting at the Sz′echenyi thermal bath (s for short) and ending at the Tomb of G¨ ul Baba (t for short).

你被強制要求參加一個賽跑作為一個TV秀的一部分節目,比賽中你需要穿越這些街道,從s開始,到t結束。

Naturally, you want to complete the race as quickly as possible, because you will get more promo- tional contracts the better you perform.

很自然的,你想要盡快的完成比賽,因為你的比賽完成的越好,你就能得到更多的商業促銷合同。

However, there is a catch: any person who is smart enough to take a shortest s-t route will be thrown into the P′alv¨olgyi cave system and kept as a national treasure. You would like to avoid this fate, but still be as fast as possible. Write a program that computes a strictly-second-shortest s-t route.

但是,有一個需要了解的是,如果有人過於聰明找到從s到t的最短路線,那麽他就被扔到國家極品人類保護系統中作為一個國家寶藏收藏起來。你顯然要避免這種事情的發生,但是也想越快越好。寫一個程序來計算一個從s到t的嚴格次短路線吧。

Sometimes the strictly-second-shortest route visits some nodes more than once; see Sample Input 2 for an example.

有的時候,嚴格次短路線可能訪問某些節點不止一次。樣例2是一個例子。

輸入描述 Input Description

The ?rst line will have the format N M, where N is the number of nodes in Budapest and M is the number of edges. The nodes are 1,2,...,N; node 1 represents s; node N represents t. Then there are M lines of the form A B L, indicating a one-way street from A to B of length L. You can assume that A != B on these lines, and that the ordered pairs (A,B) are distinct.

第一行包含兩個整數N和M,N代表布達佩斯的節點個數,M代表邊的個數。節點編號從1到N。1代表出發點s,N代表終點t。接下來的M行每行三個整數A B L,代表有一條從A到B的長度為L的單向同路。你可以認為A不等於B,也不會有重復的(A,B)對。

輸出描述 Output Description

Output the length of a strictly-second-shortest route from s to t. If there are less than two possible lengths for routes from s to t, output ?1.

輸出從s到t的嚴格次短路的長度。如果從s到t的路少於2條,輸出-1。

樣例輸入 Sample Input

樣例輸入1:

4 6

1 2 5

1 3 5

2 3 1

2 4 5

3 4 5

1 4 13

樣例輸入2:

2 2

1 2 1

2 1 1

樣例輸出 Sample Output

樣例輸出1:

11

樣例輸出2:

3

數據範圍及提示 Data Size & Hint

對於樣例1:

There are two shortest routes of length 10 (1 → 2 → 4,1 → 3 → 4) and the strictly-second- shortest route is 1 → 2 → 3 → 4 with length 11.

對於樣例2:

The shortest route is 1 → 2 of length 1, and the strictly-second route is 1 → 2 → 1 → 2 of length 3.

思路:次短路模板 註意要判斷該圖中是否有最短路

#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;

#define LOOP(i, n) for (int i = 1; i <= n; ++i)
const int MAX_NODE = 50005;
const int MAX_EDGE = 100005 << 1;
const int INF = 0x3f3f3f3f;

struct Node;
struct Edge;

struct Node {
    int Id, Dist, Dist2;
    bool Inq;
    Edge *Head;
} _nodes[MAX_NODE], *Start, *Target;
int _vCount;

struct Edge {
    int Weight;
    Node *From, *To;
    Edge *Next;
    Edge() {}
    Edge(Node *from, Node *to, Edge *next, int weight) :
        From(from), To(to), Next(next), Weight(weight) {}
} *_edges[MAX_EDGE];
int _eCount;

void Init(int vCount) {
    memset(_nodes, 0, sizeof _nodes);
    _vCount = vCount;
    _eCount = 0;
    Start = 1 + _nodes;
    Target = vCount + _nodes;
}

void AddEdge(Node *from, Node *to, int weight) {
    Edge *e = _edges[++_eCount] = new Edge(from, to, from->Head, weight);
    e->From->Head = e;
}

void Build(int uId, int vId, int weight) {
    Node *u = uId + _nodes, *v = vId + _nodes;
    u->Id = uId;
    v->Id = vId;
    AddEdge(u, v, weight);
}

void SPFA() {
    LOOP(i, _vCount)
    _nodes[i].Dist = _nodes[i].Dist2 = INF;
    static queue<Node*> q;
    Start->Dist = 0;
    Start->Dist2 = INF;
    Start->Inq = true;
    q.push(Start);
    while (!q.empty()) {
        Node *u = q.front();
        q.pop();
        u->Inq = false;
        for (Edge *e = u->Head; e; e = e->Next) {
            bool relaxOk = false;
            if (u->Dist + e->Weight < e->To->Dist) {
                e->To->Dist2 = e->To->Dist;
                e->To->Dist = u->Dist + e->Weight;
                relaxOk = true;
            }
            else if (u->Dist + e->Weight > e->To->Dist && u->Dist + e->Weight < e->To->Dist2) {
                e->To->Dist2 = u->Dist + e->Weight;
                relaxOk = true;
            }
            if (u->Dist2 + e->Weight < e->To->Dist2) {
                e->To->Dist2 = u->Dist2 + e->Weight;
                relaxOk = true;
            }
            if (relaxOk && !e->To->Inq) {
                e->To->Inq = true;
                q.push(e->To);
            }
        }
    }
}

int main() {
    int totNode, totEdge;
    int uId, vId, weight;
    scanf("%d%d", &totNode, &totEdge);
    Init(totNode);
    LOOP(i, totEdge) {
        scanf("%d%d%d", &uId, &vId, &weight);
        Build(uId, vId, weight);
    }
    SPFA();
    if (Target->Dist2 == INF) printf("-1\n");
    else printf("%d\n", Target->Dist2);
    return 0;
}

codevs 1269 匈牙利遊戲