Codeup墓地-问题 B: 算法7-16:弗洛伊德最短路径算法
題目描述
在帶權(quán)有向圖G中,求G中的任意一對(duì)頂點(diǎn)間的最短路徑問(wèn)題,也是十分常見(jiàn)的一種問(wèn)題。
解決這個(gè)問(wèn)題的一個(gè)方法是執(zhí)行n次迪杰斯特拉算法,這樣就可以求出每一對(duì)頂點(diǎn)間的最短路徑,執(zhí)行的時(shí)間復(fù)雜度為O(n3)。
而另一種算法是由弗洛伊德提出的,時(shí)間復(fù)雜度同樣是O(n3),但算法的形式簡(jiǎn)單很多。
可以將弗洛伊德算法描述如下:
?
在本題中,讀入一個(gè)有向圖的帶權(quán)鄰接矩陣(即數(shù)組表示),建立有向圖并按照以上描述中的算法求出每一對(duì)頂點(diǎn)間的最短路徑長(zhǎng)度。
?
輸入
輸入的第一行包含1個(gè)正整數(shù)n,表示圖中共有n個(gè)頂點(diǎn)。其中n不超過(guò)50。
以后的n行中每行有n個(gè)用空格隔開(kāi)的整數(shù)。對(duì)于第i行的第j個(gè)整數(shù),如果大于0,則表示第i個(gè)頂點(diǎn)有指向第j個(gè)頂點(diǎn)的有向邊,且權(quán)值為對(duì)應(yīng)的整數(shù)值;如果這個(gè)整數(shù)為0,則表示沒(méi)有i指向j的有向邊。當(dāng)i和j相等的時(shí)候,保證對(duì)應(yīng)的整數(shù)為0。
輸出
共有n行,每行有n個(gè)整數(shù),表示源點(diǎn)至每一個(gè)頂點(diǎn)的最短路徑長(zhǎng)度。如果不存在從源點(diǎn)至相應(yīng)頂點(diǎn)的路徑,輸出-1。對(duì)于某個(gè)頂點(diǎn)到其本身的最短路徑長(zhǎng)度,輸出0。
請(qǐng)?jiān)诿總€(gè)整數(shù)后輸出一個(gè)空格,并請(qǐng)注意行尾輸出換行。
樣例輸入
<span style="color:#333333">4 0 3 0 1 0 0 4 0 2 0 0 0 0 0 1 0 </span>樣例輸出
<span style="color:#333333">0 3 2 1 6 0 4 7 2 5 0 3 3 6 1 0 </span>提示
?
在本題中,需要按照題目描述中的算法完成弗洛伊德算法,并在計(jì)算最短路徑的過(guò)程中將每個(gè)頂點(diǎn)是否可達(dá)記錄下來(lái),直到求出每一對(duì)頂點(diǎn)的最短路徑之后,算法才能夠結(jié)束。
?
相對(duì)于迪杰斯特拉算法,弗洛伊德算法的形式更為簡(jiǎn)單。通過(guò)一個(gè)三重循環(huán),弗洛伊德算法可以方便的求出每一對(duì)頂點(diǎn)間的最短距離。
?
另外需要注意的是,為了更方便的表示頂點(diǎn)間的不可達(dá)狀態(tài),可以使用一個(gè)十分大的值作為標(biāo)記。而在題目描述中的算法示例使用了另外一個(gè)三維數(shù)組對(duì)其進(jìn)行表示,這使原本的O(n3)時(shí)間復(fù)雜度增長(zhǎng)到了O(n4),這也是需要自行修改的部分。
?
#include <iostream> using namespace std;const int maxn = 50; const int inf = 1000000000; int G[maxn][maxn]; int d[maxn][maxn]; int n; //n個(gè)頂點(diǎn),不超過(guò)50void ShortestPan_FLOYD() {int v, w, i, j, k;for(v = 0; v < n; v++){for(w = 0; w < n; w++){d[v][w] = G[v][w];}}for(k = 0; k < n; k++){for(i = 0; i < n; i++){for(j = 0; j < n; j++){if(d[i][k] + d[k][j] < d[i][j]){d[i][j] = d[i][k] + d[k][j];}}}} }int main() {scanf("%d", &n);for(int i = 0; i < n; i++){for(int j = 0; j < n; j++){scanf("%d", &G[i][j]);if(G[i][j] == 0 && i != j)//不可達(dá){G[i][j] = inf;}}}ShortestPan_FLOYD();for(int i = 0; i < n; i++){for(int j = 0; j < n; j++){if(d[i][j] == 0){if(i == j) printf("0 ");}else if(d[i][j] == inf){printf("-1 ");}else{printf("%d ", d[i][j]);}}printf("\n");}return 0; }?
總結(jié)
以上是生活随笔為你收集整理的Codeup墓地-问题 B: 算法7-16:弗洛伊德最短路径算法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Codeup墓地-问题 A: 算法7-1
- 下一篇: Codeup-问题 C: 最短路径