Floyd算法的精髓在於動態規划的思想,即每次找最優解時都建立在上一次最優解的基礎上,當算法執行完畢時一定是最優解
對於鄰接矩陣w,w保存最初始情況下任意兩點間的直接最短距離,但沒有加入中繼點進行考慮
如w[1][2]=20,即表示點1與點2的當前最短距離(直接距離)為20
對於路徑矩陣path,保存了點i到點j的最短路徑中下一個點的位置,
如path[1][2]=0,表示1->2的路徑中的下一個點為結點0
Floyd算法對所有中繼點在任意兩點中進行循環遍歷.即k從0-n時考慮(i->k,k->j)的路徑是否小於(i->j)的路,如果小於即更新鄰接矩陣w的值與path矩陣中的值,使其始終保持最短
圖解如下:
代碼用例:
代碼如下
點擊查看代碼
#include<iostream>
#include<fstream>
#include<vector>
using namespace std;
const int MAX = 999;
class Solution {
public:
void GetPath(vector<vector<int>>vec,int n) {
vector<vector<int>>path(n);
//初始化
for (int i = 0; i != n; i++)
path[i].resize(n);
for(int i=0;i!=n;i++)
for (int j = 0; j != n; j++) {
if (vec[i][j] != MAX)path[i][j] = j;
else path[i][j] = -1;
}
for (int i = 0; i < n; i++)path[i][i] = -1;
for(int k=0;k!=n;k++)
for(int i=0;i!=n;i++)
for (int j = 0; j != n; j++) {
if (vec[i][k] + vec[k][j] < vec[i][j]) {
vec[i][j] = vec[i][k] + vec[k][j];
path[i][j] = path[i][k];
}
}
for (int i = 0; i != n; i++)
{
cout << "\nStating from vertex: " << i << endl;
bool flag = 0;
for (int j = 0; j != n; j++)
if (j != i && vec[i][j] < MAX) {
flag = 1;
cout << i << "->" << j << ":distance=" << vec[i][j] << ": " << i;
int k = path[i][j];
while (k != j) {
cout << "->" << k;
k = path[k][j];
}
cout << "->" << j << endl;
}
if (!flag)cout << "there's no path while starting from "<<i<<endl;
}
}
};
int main() {
ifstream putIn("D:\\Input.txt", ios::in);
int num;
int finalCount = 0;
putIn >> num;
const int x = num;
vector<vector<int>>myVector(num);
//myVector:帶權鄰接矩陣
for (int i = 0; i < num; i++)
myVector[i].resize(num);
for (int i = 0; i < num; i++)
for (int j = 0; j < num; j++) {
int temp;
putIn >> temp;
myVector[i][j] = temp;
}
Solution solution;
cout << "Input文件中的鄰接矩陣為\n";
for (auto x : myVector) {
for (auto y : x)cout << y << '\t';
cout << endl;
}
solution.GetPath(myVector,num);
return 0;
}