Dijkstra演算法多條最短路徑下最短路徑的記錄

2021-09-25 20:39:47 字數 1505 閱讀 4847

1. 我們在使用dijkstra演算法求解源點到其餘頂點的最短路徑的時候,在大多數情況下最短路徑是只有一條的,但是也有可能存在著多條最短路徑的情況,所以之前使用整型的pre陣列來記錄當前節點的前驅節點的方法就不再適用這個問題了,所以需要另外的資料結構來進行記錄,而題目中告訴我們可能存在著多條最短的路徑的時候往往會要求在多條最短路徑下的另外乙個條件,比如是邊權之和最小或者最大,點權之和最小或者最大,我們最簡單的想法就是先記錄下所有的最短路徑,然後使用dfs來選擇出在滿足多條最短路徑下條件的的那一條路徑

2. 下面是具體的過程:

① 使用dijkstra演算法記錄所有的最短路徑

由於此時需要記錄所有的最短路徑,因此每個節點就會存在著多個前驅節點,這樣原先pre陣列只能夠記錄乙個前驅節點的方法就不再適用,為了適應多個前驅的情況,不妨把陣列定義為vector型別"vector pre[maxsize]",這樣對於每乙個節點v來說,pre[v]就是乙個變長的陣列,裡面用來存放節點v的所有能夠產生最短路徑的前驅節點,例如對於下面的圖,pre陣列的情況如下所示(假如需要查詢某個頂點u是否在v的前驅中的題目,也可以將pre陣列宣告成set陣列,此時使用pre[v].count查詢會更加方便一點):

通過上面vector型別的pre陣列,就可以使用dfs來獲取所有的最短路徑:

、、下面是具體的pre陣列求解的過程:

1)首先,假如d[u] + g[u][v] < d[v]說明以u作為中介點可以使d[v]更優,此時需要令v的前驅節點為u,並且即便原先的pre[v]存放了若干個節點都應該清空,然後再新增u,因為正是因為這個中介點才使得到達v這個節點的路徑變短,所有之前到達v的所有節點都需要清除,然後將u節點新增進去

if(d[u] + g[u][v] < d[v])
2)如果d[u] + g[u][v] ==d[v]說明以u為中介點可以找到一條距離相等的路徑,因此之前v的前驅節點需要在原先的基礎上新增上u節點,而不必清空pre[v]

if(d[u] + g[u][v] == d[v])
經過上面的兩個步驟就完成了pre陣列的記錄多條最短路徑的求解過程

3. 下面是完整的**:

vector pre[maxsize];

void dijstra(int s)

} if(u == -1) return;

vis[u] = true;

for(int v = 0; v < n; v++)

}else if(d[u] + g[u][v] == d[v])

} }

}

獲取多條最短路徑的Dijkstra演算法

dijkstra演算法是單源最短路徑經典演算法,一般用於所有邊的權為非負數的情況下,有向圖和無向圖均可。效率方面 儲存圖模型的資料結構有很多種,使用鄰接矩陣的話其空間複雜度都為o e 2 而如果是稀疏圖,使用鄰接鍊錶更划算,空間複雜度為o v e 在每次搜尋離起點最近的點方面,這裡用的還是vecto...

最短路 Dijkstra演算法

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

dijkstra最短路演算法

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