算法——Floyd-Warshall算法

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;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值