最短路 Dijkstra演算法

2021-07-28 04:37:13 字數 1090 閱讀 7213

這是一類求單源最短路的演算法,也就是求某乙個頂點到其他所有頂點的最短路。它是按照最短路徑遞增的順序來計算的。

先說一下大體思路:將圖中的頂點分為兩個集合,s,v-s。s儲存已經求出最短路徑的頂點,v-s儲存未求出最短路的頂點。然後演算法就是不斷額的求出v-s中頂點的最短路,然後把它加入s中,直到所有頂點的最短路都求出,也就是v-s是空集。

選擇鄰接矩陣的資料結構來儲存圖。

下面先交代一下需要引進的資料結構:

一堆陣列s[i]來記錄v0到vi的最短是否已經確定。用1 0 或者true false表示;

一堆陣列path[i]來記錄vi所在當前的最短路徑的vi的直接前驅。初始值:如果v0 vi之間有弧,path[i]初始值為v0 ,否則為-1.

一堆陣列d[i],記錄v0到vi的當前最短(注意是當前最短,而不是最後求出的真正的最短路的長度)路徑的長度。初始值:如果v0 vi 之間有弧,d[i]為弧上的權值,否則為∞

演算法核心:

每一次遍歷尋找當前未確定最短路徑的頂點到v0 的最短路中的最小值,將這條最短路的終點k加入集合s。而此時,集合s中已經有了兩個頂點了,再求其他點vi的最短路的時候,就有了乙個中繼的頂點。就是說,可能存在d[i]>d[k]+g[k][vi]的情況,這時候就要更新d[i]也就是v0到vi的當前最短路徑,並把vi的直接前驅改為vk。這個更新當前最短路的步驟被稱為鬆弛操作。更新完畢以後再尋找當前路徑中的最小值,然後再重複上述步驟。

這裡我之前有乙個疑惑,就是當s 集合裡面多於兩個頂點的時候,只考慮通過最後一次加入集合s的那個點來進行鬆弛操作,那其他已經加入s集合的頂點不考慮會不會錯過最優解呢?嗯,,確實是自己的思維還是不夠靈活。比如說,點a b c 依次加入了集合s,那麼你在以c點為中繼點來更新當前最短路之前,d[i]的值就已經是根據點b更新過了的,同樣你在根據b更新之前的d[i]的值是已經根據a更新過了的,所以不必擔心會錯過最優解。吶,之所以稱為更新,就是乙個不斷優化的過程,是吧。

對於那個記錄vi直接前驅的陣列path[i]是用來最終遞迴輸出最短路依次經過的點的。

下面是核心**:

for(int i=0;i>a>>b>>c;

g[a][b]=c;

}//用鄰接矩陣儲存圖

for(int i=0;i

最短路 Dijkstra演算法

dijksitra演算法求最短路僅僅適用於不存在右邊是負權的情況 bellman ford演算法沒有這乙個限制 主要特點是從起點為中心向外層層擴充套件,直到擴充套件到終點為止。即乙個最短路路徑中經過的所有點這條路均是其最短路。反證法易證 dijkstra基本思路 找到最短距離已經確定的頂點,從它出發...

dijkstra最短路演算法

dijkstra演算法 1.定義概覽 dijkstra 迪傑斯特拉 演算法是典型的單源最短路徑演算法,用於計算乙個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴充套件,直到擴充套件到終點為止。dijkstra演算法是很有代表性的最短路徑演算法,在很多專業課程中都作為基本內容有詳細的...

最短路 Dijkstra演算法

對有向圖,無向圖均有效。要求,權值為正。貪心。每次取距離s最近的點,來更新其他點。bfs。將權值看成單位長度的路徑之和,最近的點即bfs最先達到的點。定義delta u,v 若u,v不可達,值為無窮。若u,v可達,則delta u,v 即u,v間最短距離。鬆弛操作 relax u,v,w if d ...