poj3255 次短路Dijkstra

挑战程序设计竞赛上的题目。

题意:给一个边权都是正的无向图,求1到n的次短路。

分析:

考虑s->v的次短路,假设s-v的最短路为s->…->u>v,到v的次短路等于到u的次短路加上cost(u,v)和到k的最短路加上cost(k,v)中的最小但是大于u->v的最短路的值。那么只要保证在求最短路的过程中同时保存次短路就可以了。

代码。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#define INF 0x7fffffff
using namespace std;
typedef pair<int,int> P;
struct edge{
    int to,v;
    edge(int to,int v):to(to),v(v){}
    edge(){}
};
const int maxn = 5005;
const int maxe = 100005;
int V,E;
vector<edge> g[maxn];
int d[maxn],d2[maxn];//最短距离和次短距离
void dijkstra(int s)
{
    priority_queue<P,vector<P>,greater<P> > pq;
    for(int i=1;i<=V;i++)
    {
        d[i]=INF;
        d2[i]=INF;
    }
    d[s]=0;
    pq.push(P(0,s));
    while(pq.size())
    {
        P nowe=pq.top();pq.pop();
        if(nowe.first>d2[nowe.second]) continue;  //如果这个距离比当前次短路长continue
        for(int v=0;v<(int)g[nowe.second].size();v++)
        {
            edge nexte=g[nowe.second][v];
            int dis=nowe.first+nexte.v;
            if(d[nexte.to]>dis)
            {
                swap(dis,d[nexte.to]);
                pq.push(P(d[nexte.to],nexte.to));
            }
            if(d2[nexte.to]>dis&&d[nexte.to]<dis)//保证最短路是小于这个次短路的
            {
                d2[nexte.to]=dis;
                pq.push(P(d2[nexte.to],nexte.to));//次短路的点进入pq
            }
        }
    }
}
int main()
{
    int s;//起点
    scanf("%d%d",&V,&E);
    {
        for(int i=1;i<=V;i++)
            g[i].clear();
        for(int i=1;i<=E;i++)
        {
            int f,t,v;
            scanf("%d%d%d",&f,&t,&v);
            g[f].push_back(edge(t,v));
            g[t].push_back(edge(f,v));
        }
        s=1;//这题默认起点为1
        dijkstra(s);
        printf("%d\n",d2[V]);
    }
    return 0;
}
    原文作者:Dijkstra算法
    原文地址: https://blog.csdn.net/NGccc/article/details/45061745
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞