POJ-3255 Roadblocks(次短路)

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: A, B, 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中多加个dist2求次短路,保证符合限制条件更新,必须大于最短路且小于上次被记录的次短路

#include<stdio.h>///次短路
#include<queue>///大体和最短路差不多,其实就是用最短路而计算出的次短路
#include<string.h>
#include<algorithm>
#include<vector>
using namespace std;
int dist[5008],dist2[5008];///最短路和次短路分别用数组存
struct edge
{
    int to,val;
    edge(int a=0,int b=0):to(a),val(b) {}///结构体构造函数
    bool operator <(const edge &a)const///结构体重载运算符
    {
        if(val==a.val)return to>a.to;
        return val>a.val;///此处虽然是大于号,但是在优先队列中是从小到大排列,队首为最小值
    }
};
vector<edge>v[5008];
void dijkstra(int s)
{
    memset(dist,0x3f,sizeof(dist));
    memset(dist2,0x3f,sizeof(dist2));
    priority_queue<edge>q;
    q.push(edge(s,0));///注意起点从1开始而不是从0
    while(!q.empty())
    {
        edge top=q.top();///取出最小值
        q.pop();
        for(int i=0; i<v[top.to].size(); i++)
        {
            edge tmp=v[top.to][i];///和最短路一样,先更新最短路,遍历取出节点所能到达的所有节点,更新所有能到达节点的最短路,这里的新权值,暂时用一个dis做临时存储
            int dis=tmp.val+top.val;
            if(dist[tmp.to]>dis)///若新权值比记录的最短路数组要小
            {
                swap(dist[tmp.to],dis);///更新最短路!且,临时存储这个被更换的"前最短路",用来之后更新次短路,因为这个最短路是仅次于新权值的最短路。
                q.push(edge(tmp.to,dist[tmp.to]));///将新最短路塞入队列
            }
            if(dist2[tmp.to]>dis&&dis>dist[tmp.to])///无论这个dis是否被之前的最短路通过更换来更新过,它都是一个在最短路基础上加上新权值而得到的权值,只要符合小于原次短路且大于最短路的条件
            {///都能用来更新次短路
                dist2[tmp.to]=dis;
                q.push(edge(tmp.to,dist2[tmp.to]));///将次短路放回队列中继续更新(用于更新次短路)
            }
        }
    }
}
int main()
{
    int n,r,to,val,from;
    while(scanf("%d%d",&n,&r)!=EOF)
    {
        for(int i=0; i<=5000; i++)v[i].clear();
        for(int i=0; i<r; i++)
        {
            scanf("%d%d%d",&from,&to,&val);
            v[from].push_back(edge(to,val));///无向图
            v[to].push_back(edge(from,val));
        }
        dijkstra(1);
        printf("%d\n",dist2[n]);
    }
}
/*
有一个关系是 dist2【i】> dx >dist[i] 那么这个dx是可以更新dist2的,
然后将这个dx更新之后又放入优先队列中,用来做下一次可能出现的次短
路的更新,这样,也许没有进到第一个if里去更新最短路,但是仍然有可
能用于构造下一个次短路,所以第二个push应该是用来更新不是最短路的次短路
*/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值