POJ 3255 Roadblocks

Description

Bessie has moved to a small farm and sometimes enjoys returning to visit one of her best friends. She does not want to get to her old home too quickly, because she likes the scenery along the way. She has decided to take the second-shortest rather than the shortest path. She knows there must be some second-shortest path.

The countryside consists of R (1 ≤ R ≤ 100,000) bidirectional roads, each linking two of the N (1 ≤ N ≤ 5000) intersections, conveniently numbered 1..N. Bessie starts at intersection 1, and her friend (the destination) is at intersection N.

The second-shortest path may share roads with any of the shortest paths, and it may backtrack i.e., use the same road or intersection more than once. The second-shortest path is the shortest path whose length is longer than the shortest path(s) (i.e., if two or more shortest paths exist, the second-shortest path is the one whose length is longer than those but no longer than any other path).

Input

Line 1: Two space-separated integers: N and R 
Lines 2..R+1: Each line contains three space-separated integers: AB, and D that describe a road that connects intersections A and B and has length D (1 ≤ D ≤ 5000)

Output

Line 1: The length of the second shortest path between node 1 and node N

Sample Input

4 4
1 2 100
2 4 200
2 3 250
3 4 100

Sample Output

450

Hint

Two routes: 1 -> 2 -> 4 (length 100+200=300) and 1 -> 2 -> 3 -> 4 (length 100+250+100=450)
我們把路口看作頂點,把道路看作邊的無向圖。雖然用Dijkstra算法可以簡單地求得最短路,但是次短路該怎麼求呢?Dijkstra算法的思路是依次確定尚未確定的頂點中距離最小的頂點。按照這個思路稍加修改,就可以簡單地求得次短路了。

到某個頂點v的次短路要麼是到其他頂點u的最短路再加上u--> v 的邊,要麼是到u的次短路再加上u --> v 的邊,因此所要求的就是到所有頂點的最短路和次短路。因此對於每個頂點,我們記錄的不僅僅是最短距離,還有次短的距離。接下去只要用與Dijkstra算法相同的做法,不斷更新這兩個距離就可以求出次短路了。
次短路的判斷條件:
 d2>dist[e.to]  && d2<dist2[e.to]   d2大於最短距離又小於上一次的次短距離。
代碼如下:
#include<iostream>
#include<vector>
#include<queue>
#include<utility>
#include<functional>
#include<algorithm>
using namespace std;
//#define  P pair<int,int>//first是距離源點s的距離,second是當前頂點
typedef pair<int, int> P;
const int MAXV = 5000;
const int INF = 0x7fffffff;
struct edge//採用鄰接表表示
{
    int to;
    int cost;
};
int N;//頂點個數
vector<edge> G[MAXV];
int dist[MAXV];//各頂點到起點s的最短距離
int dist2[MAXV];//次短距離
void solve()
{
    //通過指定greater<P>參數,推按照first從小到到的順序取出值
    priority_queue<P, vector<P>, greater<P>> que;
    fill(dist, dist + N, INF);
    fill(dist2, dist2 + N, INF);
    dist[0] = 0;
    que.push(P(0, 0));

    while (!que.empty())
    {
        P p = que.top();
        que.pop();
        int v = p.second;
        int d = p.first;
        if (d > dist2[v])
            continue;
        for (int i = 0; i < G[v].size(); i++)
        {
            edge& e = G[v][i];
            int d2 = d + e.cost;
            if (dist[e.to]>d2)
            {
                swap(dist[e.to], d2);
                //que.push(P(d2,e.to))是絕對不行的!!!因爲d2的值已經變了
                que.push(P(dist[e.to], e.to));
            }
            if (dist2[e.to] > d2&&dist[e.to] < d2)//這個地方簡潔有力,需要深刻理解
            {
                dist2[e.to] = d2;
                que.push(P(dist2[e.to], e.to));
            }
        }
    }
    printf("%d\n", dist2[N - 1]);
}
int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("D:\\in.txt", "r", stdin);
    freopen("D:\\out.txt", "w", stdout);
#endif
    int R;
    cin >> N >> R;
    int a(0), b(0), d(0);
    edge ee;
    for (int i = 0; i < R; i++)//圖的鄰接矩陣存取
    {
        cin >> a >> b >> d;
        ee.to = b - 1;
        ee.cost = d;
        G[a - 1].push_back(ee);
        ee.to = a - 1;
        G[b - 1].push_back(ee);
    }
    solve();
    return 0;
}

發佈了86 篇原創文章 · 獲贊 10 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章