圖論中求最短路的演算法有很多,這裡使用一道模板題來介紹可以求單源最短路的dijkstra演算法
acwing 849. dijkstra求最短路 i
求乙個源點到 除了這個點之外其他所有的點 的最短距離, 不需要記錄每條路徑
這題一直困惑著我的是,為什麼一開始找的最小的最短距離就是確定的最短距離?
想了好久,後來慢慢就理解了。
首先dijkstra演算法只能處理邊權為正的圖的最最短距離,既然所有邊權都是正數,那麼我們可以這樣來想:
遍歷了源點到所有點的距離,這裡會發現源點到某乙個點的距離是最小的,那麼有沒有可能
源點經過其它點然後再到這個點 的距離會更小嗎???!!!
答案是絕對不可能的!
因為權值(i,j) > 權值(i,k), 且權值(j,k) > 0
所以權值(i,j) + 權值(j,k) > 權值(i,k)
這也是為什麼dijkstra演算法只能用來處理所有邊權為正的圖,如果有一條邊的權值為負,那麼以上的證明就不會成立
1.先輸入點數和邊數,然後輸入全部有向邊的資料,稠密圖使用鄰接矩陣,稀疏圖使用鄰接表或者鏈式前向星
2.初始化d[1] = 0 //因為第乙個點是源點,而它到自身的距離就是0,暫時不初始化st[1],等下再用
3.接下來做n次操作,每次操作都可以確定源點到乙個點的最短距離
4.每次操作時,先把起點到所有點的最短距離遍歷一次,利用貪心的思想,把最小的最短距離所在的那個點(這個點沒有被確定為最短距離)儲存下來
5.因為當前點到起點的最短距離是 沒有被確定的所有點中最短的,因此使用這個點來更新起點到所有點的距離
6.重複n次4、5的步驟,這樣就找到乙個點到所有點的最短距離
#include
#include
#include
using
namespace std;
const
int n =
505, inf =
0x3f3f3f3f
;/*g為鄰接矩陣,用來儲存稠密圖,d[i]表示i號點到源點的距離,
n為點數,m為邊數*/
int g[n]
[n], d[n]
, n, m;
/*st[i]為true,表示i號點到源點的最短距離已經確定;
st[i]為false,表示i號點到源點的最短距離還沒有確定*/
bool st[n]
;int
dijkstra()
//如果源點到n號點的距離為無窮大級別,那麼就返回-1;否則返回距離
if(d[n]
> inf /2)
return-1
;return d[n];}
intmain()
cout <<
dijkstra()
;}
時間複雜度:o(nn)
空間複雜度:o(nn)
n為點數
dijkstra演算法求最短路
演算法思想 用乙個dis陣列記錄源點到其他各點的路徑,例如 如果v0是源點,那麼dis 1 就表示v0到v1的最短距離 用乙個vis陣列記錄頂點有沒有被當成出發點。如果第乙個出發點 源點 到別的點的路都已經走完了,那就找一下個目前距離源點最近的點作為出發點,標誌為1。然後繼續尋找最短路徑,如果dis...
Dijkstra演算法求最短路徑
參考文獻 dijkstra一般的表述通常有兩種方式,一種用永久和臨時標號方式,一種是用open,close表方式,drew為了和下面要介紹的 a 演算法和 d 演算法表述一致,這裡均採用open,close表的方式。大概過程 建立兩個表,open,close。open表儲存所有已生成而未考察的節點,...
Dijkstra演算法求最短路徑
dijkstra演算法用來求最短距離 已經實現了 那麼最短路徑 如何求解並列印出來呢?此處的方法是記錄路徑中結點的前驅 if v未被訪問 以u為中介點可以使起點s到頂點v的最短距離d v 更優 程式具體實現,鄰接矩陣版 n為頂點數,maxv為最大頂點數 int n,g maxv maxv 起點到達各...