在帶權有向圖G中,求G中的任意一對頂點間的最短路徑問題,也是十分常見的一種問題。
解決這個問題的一個方法是執行n次迪傑斯特拉算法,這樣就可以求出每一對頂點間的最短路徑,執行的時間複雜度為O(n3)。
而另一種算法是由弗洛伊德提出的,時間複雜度同樣是O(n3),但算法的形式簡單很多。
在本題中,讀入一個有向圖的帶權鄰接矩陣(即數組表示),建立有向圖并使用Floyd算法求出每一對頂點間的最短路徑長度。
輸入格式:
輸入的第一行包含1個正整數n,表示圖中共有n個頂點。其中n不超過50。
以後的n行中每行有n個用空格隔開的整數。對于第i行的第j個整數,如果大于0,則表示第i個頂點有指向第j個頂點的有向邊,且權值為對應的整數值;如果這個整數為0,則表示沒有i指向j的有向邊。
當i和j相等的時候,保證對應的整數為0。
輸出格式:
共有n行,每行有n個整數,表示源點至每一個頂點的最短路徑長度。
如果不存在從源點至相應頂點的路徑,輸出-1。對于某個頂點到其本身的最短路徑長度,輸出0。
請在每個整數後輸出一個空格,并請注意行尾輸出換行。
輸入樣例:
4
0 3 0 1
0 0 4 0
2 0 0 0
0 0 1 0
輸出樣例:
0 3 2 1
6 0 4 7
2 5 0 3
3 6 1 0
代碼長度限制
16 KB
時間限制
400 ms
記憶體限制
64 MB
#include <bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
const int N = 55;
int n;
int d[N][N];
void floyd()
{
for (int k = 0; k < n; k++)
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cin >> d[i][j];
if (d[i][j] == 0) d[i][j] = inf;
}
}
floyd();
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (i == j) cout << "0 ";
else if (d[i][j] == inf) cout << "-1 ";
else cout << d[i][j] << " ";
}
cout << endl;
}
}