dijkstra求次短路徑
阿新 • • 發佈:2018-12-27
之前用Dijkstra演算法求過最短路徑,求次短路徑在之前的方法上做一下修改就可以。
求從s到t的次短路徑有兩種情況:1、起點s到某個頂點u的最短路+d(u,t)。2、起點到某個頂點u的次短路+d(u,t)。
所以更新路徑的時候需要把最短路徑和次短路徑兩個都記錄下來。
具體見程式碼:
參考自:http://blog.csdn.net/u014800748/article/details/44923679#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]); }
習題: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
(存在重複走的路徑)