【算法】Dijkstra算法(單源最短路徑問題) 鄰接矩陣和鄰接表實現
阿新 • • 發佈:2017-10-23
當前 prior 排序 發的 單源最短路徑 fine emp eat col
Dijkstra算法可使用的前提:不存在負圈。
負圈:負圈又稱負環,就是說一個全部由負權的邊組成的環,這樣的話不存在最短路,因為每在環中轉一圈路徑總長就會邊小。
算法描述:
1.找到最短距離已確定的頂點,從它出發更新相鄰頂點的最短距離。
2.以後不需要再關心1中的“最短距離已確定的頂點”。
C++代碼:
#include <bits\stdc++.h> using namespace std; #define INF 2147483647 #define MAX_V 1000 #define MAX_E 2000 //單源最短路徑問題(Dijkstra算法) intcost[MAX_V][MAX_V]; //cost[u][v]表示e = (u,v)的權值 int d[MAX_V]; //頂點s出發的最短距離 bool used[MAX_V]; //標記使用過的點 int V; //頂點數 void dijkstra(int s){ fill(d, d+V, INF); fill(used, used + V, INF); d[s] = 0; while(true){ int v = -1; //找到一個距離最近的沒有使用過的點 for(int u = 0;u < V; u++){ if(!used[u] && (v == -1 || d[u] < d[v])) v = u; } //如果所有的點都被使用過了,則break if(v == -1) break; //標記當前點被使用過了 used[v] = true; //更新這個找到的距離最小的點所連的點的距離 for(int u = 0;u < V; u++){ d[u]= min(d[u], d[v] + cost[v][u]); } } } int main(){ }
我們會發現,如果邊比較少的話,用鄰接矩陣特別耗時間和空間。
時間復雜度O(V^2)
所以邊比較少的話,有一種鄰接矩陣的寫法,對其優化一下,
時間復雜度O(E*log(V))
C++代碼:
#include <bits\stdc++.h> using namespace std; #define INF 2147483647 #define MAX_V 1000 #define MAX_E 2000 //單源最短路徑問題(Dijkstra算法) struct edge{ int to,cost; }; typedef pair<int, int> P; //first是最短距離,second是頂點的編號 int V; //頂點數 vector <edge> G[MAX_V]; // 邊 int d[MAX_V]; // d[i]表示i離源點的最短距離 void dijkstra(int s){ //通過指定greater<P> 參數,優先隊列是用堆實現的,堆按照first從小到大排序。 priority_queue<P, vector<P>, greater<P> > que; fill(d, d+V, INF); d[s] = 0; //加源點入最小堆 que.push(P(0,s)); while(!que.empty()){ //取出堆頂的點,也就是距離最小的點 P p = que.top(); que.pop(); int v = p.second; //如果這個點在加入隊列之後更新過,就不必再更新 if(d[v] < p.first) continue; //遍歷當前點相鄰的所有點 for(int i = 0;i < G[v].size(); i++){ edge e = G[v][i]; //如果這個點能更新其他點,就將被更新的那個點加入隊列。 if(d[e.to] > d[v] + e.cost){ d[e.to] = d[v] + e.cost; que.push(P(d[e.to], e.to)); } } } } int main(){ }
【算法】Dijkstra算法(單源最短路徑問題) 鄰接矩陣和鄰接表實現