dijkstra求次短路径

之前用Dijkstra算法求过最短路径,求次短路径在之前的方法上做一下修改就可以。

求从s到t的次短路径有两种情况:1、起点s到某个顶点u的最短路+d(u,t)。2、起点到某个顶点u的次短路+d(u,t)。

所以更新路径的时候需要把最短路径和次短路径两个都记录下来。

具体见代码:

#define N 100000+10  
#define INF 100000000  
typedef pair<int, int>P;  
int n,r;  
struct Edge{ int to, cost; };  
vector<Edge>G[N];  
int dist[N], dist2[N];  
void addedge(int u, int v,int w)  
{  
    G[u].push_back(Edge{ v, w });  
    G[v].push_back(Edge{ u, w });  
}  
void solve()  
{  
    priority_queue<P, vector<P>, greater<P> >q;  
    fill(dist, dist + n, INF);  
    fill(dist2, dist2 + n, INF);  
    dist[0] = 0;  
    q.push(P(0, 0));  
    while (!q.empty())  
    {  
        P u = q.top(); q.pop();  
        int v = u.second, d = u.first;  
        if (dist2[v] < d)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);  
                q.push(P(dist[e.to], e.to));  
            }  
            if (dist2[e.to]>d2&&dist[e.to] < d2)//更新次短距离  
            {  
                dist2[e.to] = d2;  
                q.push(P(dist2[e.to], e.to));  
            }  
        }  
    }  
    printf("%d\n", dist2[n - 1]);  
}  

参考自:http://blog.csdn.net/u014800748/article/details/44923679

习题:POJ3225

题意:就是求两个点之间的次短路径(如果最短路径有好多条,那么次短路径是比这些最短路径都长,但比其他路径都短的那条)

代码:

#include <stdio.h>
#include <string.h>
#include <queue>
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
#define N 5005
#define INF 111111111
struct Edge{
	int to ,w;
	bool operator <(const Edge &a)const{
		return w > a.w;
	}
};
priority_queue<Edge> Q;
vector<Edge> V[N];
int n, m;
int dis[N], dis2[N];
void init(){
	for(int i = 1; i <= n; i++){
		V[i].clear();
		dis[i] = INF;
		dis2[i] = INF;
	}
}
int dijkstra(){
	dis[1] = 0;
	Edge p, q, r;
	p.to = 1, p.w = 0;
	Q.push(p);
	while(!Q.empty()){
		p = Q.top();
		Q.pop();
		int u = p.to;
		if(p.w > dis2[u])continue;
		for(int i = 0; i < V[u].size(); i++){
			q = V[u][i];
			int to = q.to, d = q.w + p.w;
			if(dis[to] > d){
				swap(dis[to], d);
				r.to = to, r.w = dis[to];
				Q.push(r);
			}
			if(dis[to] < d && dis2[to] > d){
				dis2[to] = d;
				r.to = to, r.w = d;
				Q.push(r);
			}
		}
	}
	return dis2[n];
}
int main(){
	int a, b, w;
	Edge p;
	while(cin>>n>>m){
		init();
		for(int i = 0; i < m; i++){
			scanf("%d%d%d", &a, &b, &w);
			p.to = b;
			p.w = w;
			V[a].push_back(p);
			p.to = a;
			V[b].push_back(p);
		}
		int len = dijkstra();
		cout<<len<<endl;
	}
	return 0;
}

其中一组不错的数据:

4 6
1 2 1
1 2 5
1 3 2
2 3 2
2 4 1
2 4 6

ans:4

本数据的次短路径为:1->2->1->2->4

(存在重复走的路径)

    原文作者:Dijkstra算法
    原文地址: https://blog.csdn.net/zhj_fly/article/details/75506896
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞