最短路徑問題(單源點和多源點)

2021-09-24 06:12:44 字數 1432 閱讀 5734

單源點

多源點演算法思想:

先初始化距離陣列d[ ] = inf ,d[1] = 0 。

根據d[v] = min( d[u] + w[u][v] , d[v] ),對所有的邊進行"鬆弛",值得注意,每一輪鬆弛都會更新至少一條最短路徑,即得到乙個最小的 d[i]。

時間複雜度: o(|v|*|w|)

bellmanford(g, w, s)

} //檢驗是否有負權邊

for( (u,v) in g )

return true;

}relax(u,v,w)

演算法思想:

維持乙個陣列的d[ n ]記錄各個點到源點的距離, s[ n ]記錄已經訪問過的點,1代表已經訪問,0代表未訪問。

每次從未訪問的點中選出 最小的d[i] , 並對其子節點進行更行距離。通過n次選取、更行後,即完成了計算所有點到單源點的距離。其中,也可以用parent[n]陣列記錄父節點。

時間複雜度: n次取出, 每次查詢n, 總時間o(n*n)

(思考:陣列d[n]可以換成乙個最優佇列,每次取出最優佇列的最小值,更新新的d 時也可以在最優佇列中更新)

//偽**:

dijkstra(); s[1] = 1;

q = v; //初始化最優佇列

while( !q.empty() ) }

}

設 i 到 j 的最短路徑p 途徑 k,路徑p(i,j)=min (p(i,k)+w(k,j)), k=1…n 。

思考遞迴方程,進而可以理解動態規劃思想。

d(i,j)(m) = min( d(i,k)(m-1)+w(k,j) ), k= 1…n

d(i,j)(m)代表第m次更新矩陣

注意第m次更新矩陣,至少可以得到路徑長為m的最優路徑

時間複雜度: n^4

dynamic() //動態規劃

演算法思想:

找中間節點k;設 i 到 j 的最短路徑p 途徑 1,2,3… k。那麼,若點k在p上,可以將路徑p分成 p1: i***k 和 p2:k***j;

即 d(i,j) (k)=min( d(i,j) (k-1), d(i,k)(k-1)+d(k,j)(k-1) )

( d(i,j)(k) 代表點i 到 點j 途徑 的點在1…k中,且d(i,j)(0) = w(i,j) )

時間複雜度:n^3

floywarshall()

return d(n);

}

多源點最短路徑

給出s個起點,給出t個終點,求出所有起點到終點的最短路中的最短的乙個.構建乙個超級源點,與每乙個起點相連,權值為0 構建乙個超級終點,與每乙個終點相連,權值為0。然後求超級源點到超級終點的最短路徑。include includeusing namespace std int first 1010 d...

單源點最短路徑

include include include using namespace std 自定義比較大小,負數均視為無窮大,其他大小正常 xbool lessthen float x,float y 長度為len的s陣列是否包含e 包含e,return true bool contain int s,...

單源點最短路徑

單源點最短路徑 雨竹清風 單源最短路徑 是從某乙個源點s出發到圖中的所有的頂點之間的最短路徑。1.單源點最短路徑的變體 1 單終點最短路徑問題 找到從每乙個頂點到終點的最短路徑。可以將圖中的邊全部反向,然後求單源點最短路徑即可。2 單對頂點最短路徑問題 對於圖中的兩個頂點u和v,找到從u到v的最短路...