这一章就实现了一个Floyd算法。
其中路径的表示没有采用书上的前驱表示,而是用每一对结点中开始结点的后继来表示。
floyd_warshall.h
#pragma once
/*************************************************
Author:董小歪
Date:2016-06-24
Description:算法导论第二十五章-所有结点对的最短路径问题-Cpp代码实现
**************************************************/
#ifndef FLOYD_WARSHALL_H
#define FLOYD_WARSHALL_H
#include <iostream>
#include <vector>
using namespace std;
class Floyd_Warshall
{
public:
Floyd_Warshall(const vector<vector<int>> &_W); //构造函数
vector<vector<int>> floyd_warshall(); //Floyd算法
void show_path(); //显示计算结果
void show_vec(const vector<vector<int>> &vec);
private:
vector<vector<int>> W; //输入邻接矩阵
vector<vector<int>> path; //计算路径
vector<vector<int>> D; //计算距离
};
#endif // !FLOYD_WARSHALL_H
#include "floyd-warshall.h"
Floyd_Warshall::Floyd_Warshall(const vector<vector<int>> &_W) :W(_W)
{
int n = W.size();
path = vector<vector<int>>(n, vector<int>(n, -1));
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
if (W[i][j] < INT_MAX)
path[i][j] = j; //初始化路径。这里没有按书上的方法,存的是每一个点的后继而不是前驱。
}
vector<vector<int>> Floyd_Warshall::floyd_warshall()
{
int n = W.size();
D = W;
for (int k = 0; k < n; ++k)
{
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
if (D[i][j] > D[i][k] + D[k][j])
{
D[i][j] = D[i][k] + D[k][j]; //发现了更短的距离,取代前者
path[i][j] = path[i][k]; //更新路径
}
}
}
}
return D;
}
void Floyd_Warshall::show_path()
{
int n = W.size();
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
printf("结点%d到结点%d的最短路径是为%d,\t", i, j, D[i][j]);
int k = path[i][j];
if (k == -1)
printf("路径不存在\n");
else
{
printf("(%d", i);
while (k != j)
{
printf("->%d", k);
k = path[k][j];
}
printf("->%d)\n", j);
}
}
}
}
void Floyd_Warshall::show_vec(const vector<vector<int>> &vec)
{
for (int i = 0; i < vec.size(); ++i)
{
for (int j = 0; j < vec[i].size(); ++j)
{
if (vec[i][j] < INT_MAX / 2)
cout << vec[i][j] << "\t";
else
cout << "∞" << "\t";
}
cout << endl;
}
}
main_entrance.cpp
#include "floyd-warshall.h"
int main()
{
vector<vector<int>> W(5, vector<int>(5, INT_MAX / 2));
W[0][1] = 3; W[0][2] = 8; W[0][4] = -4;
W[1][3] = 1; W[1][4] = 7;
W[2][1] = 4;
W[3][0] = 2; W[3][2] = -5;
W[4][3] = 6;
for (int i = 0; i < W.size(); ++i) W[i][i] = 0;
Floyd_Warshall fw(W);
cout << "初始化的邻接矩阵为:" << endl;
fw.show_vec(W);
cout << endl << "Floyd计算后的邻接矩阵为:" << endl;
fw.show_vec(fw.floyd_warshall());
cout << "每两个结点之间的路径:" << endl;
fw.show_path();
system("pause");
}
测试结果: