Floyd-Warshall算法是一种用于解决图中所有顶点对之间最短路径的动态规划算法。它可以处理有向图或无向图,以及负权边(但不能处理负权回路)。
Floyd-Warshall算法采用了动态规划的思想,通过逐步更新所有顶点对之间的最短路径来求解问题。
原理:
- 初始化:首先,将图的邻接矩阵初始化为每条边的权重,如果没有边相连则用一个足够大的值表示不可达。
- 递推关系:对于每一对顶点 (i, j),我们尝试通过中间顶点k来更新它们之间的最短路径。如果经过顶点k的路径比当前路径更短,则更新最短路径。
- 重复步骤2直到更新所有的顶点对的最短路径。
下面的示例中,使用c++简单实现了Floyd-Warshall算法。首先,我们用邻接矩阵表示图,并初始化所有顶点对之间的最短路径。然后,我们通过嵌套的循环来逐步更新最短路径矩阵,直到找到所有顶点对的最短路径。
#include <iostream>
#include <vector>
using namespace std;
const int INF = 999999;
class FloydWarshall {
int V; // 顶点数
vector<vector<int>> dist; // 存储顶点对之间的最短路径
public:
FloydWarshall(int v) {
V = v;
dist.resize(V, vector<int>(V, INF));
}
// 添加边的函数
void addEdge(int src, int dest, int weight) {
dist[src][dest] = weight;
}
// Floyd-Warshall算法函数
void floydWarshall() {
// 初始化
for (int k = 0; k < V; k++) {
for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
// 如果经过顶点k的路径比当前路径更短,则更新最短路径
if (dist[i][k] + dist[k][j] < dist[i][j])
dist[i][j] = dist[i][k] + dist[k][j];
}
}
}
// 打印最短路径矩阵
cout << "最短路径矩阵:" << endl;
for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
if (dist[i][j] == INF)
cout << "INF\t";
else
cout << dist[i][j] << "\t";
}
cout << endl;
}
}
};
int main() {
int V = 4; // Number of vertices
FloydWarshall graph(V);
// Add edges
graph.addEdge(0, 1, 5);
graph.addEdge(0, 3, 10);
graph.addEdge(1, 2, 3);
graph.addEdge(2, 3, 1);
graph.floydWarshall(); // 调用Floyd-Warshall算法函数
return 0;
}