POJ 3255 Roadblocks

11 篇文章 0 订阅
5 篇文章 0 订阅

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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值