所有顶点对之间的最短路径之Floyd-Warshall算法

Floyd算法用于求最短路径。Floyd算法可以说是Warshall算法的扩展,三个for循环就可以解决问题,所以它的时间复杂度为O(n^3)。

Floyd算法的基本思想如下:从任意节点A到任意节点B的最短路径不外乎2种可能,1是直接从A到B,2是从A经过若干个节点X到B。所以,我们假设Dis(AB)为节点A到节点B的最短路径的距离,对于每一个节点X,我们检查Dis(AX) + Dis(XB) < Dis(AB)是否成立,如果成立,证明从A到X再到B的路径比A直接到B的路径短,我们便设置Dis(AB) = Dis(AX) + Dis(XB),这样一来,当我们遍历完所有节点X,Dis(AB)中记录的便是A到B的最短路径的距离。

很简单吧,代码看起来可能像下面这样:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个简单的代码示例,其中包括创建有向图和 Dijkstra 算法Floyd-Warshall 算法的实现: ```c++ #include <iostream> #include <vector> #include <queue> #include <cstring> using namespace std; const int MAXN = 1005; // 最大顶点数 const int INF = 0x3f3f3f3f; // 无穷大 struct Edge { // 边的结构体 int to; // 终点 int w; // 权重 Edge(int _to, int _w) : to(_to), w(_w) {} }; vector<Edge> G[MAXN]; // 邻接表存储图 int n, m; // 顶点数、边数 int dist[MAXN]; // 存储 Dijkstra 算法中的最短距离 int d[MAXN][MAXN]; // 存储 Floyd-Warshall 算法中的最短距离 // 初始化有向图,邻接矩阵建立有向有权重图 void CreateGraph() { cin >> n >> m; memset(d, INF, sizeof(d)); // 初始化 Floyd-Warshall 矩阵 while (m--) { int u, v, w; cin >> u >> v >> w; G[u].push_back(Edge(v, w)); // u -> v,权重为 w,加入邻接表 d[u][v] = min(d[u][v], w); // 更新 Floyd-Warshall 矩阵 } } // Dijkstra 算法求单源最短路径 void Dijkstra(int s) { memset(dist, INF, sizeof(dist)); dist[s] = 0; priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q; q.push(make_pair(0, s)); while (!q.empty()) { auto p = q.top(); q.pop(); int d = p.first; // 当前点到起点的距离 int v = p.second; // 当前点的编号 if (dist[v] < d) continue; for (int i = 0; i < G[v].size(); i++) { Edge e = G[v][i]; if (dist[e.to] > dist[v] + e.w) { dist[e.to] = dist[v] + e.w; q.push(make_pair(dist[e.to], e.to)); } } } } // Floyd-Warshall 算法求多源最短路径 void FloydWarshall() { for (int k = 1; k <= n; k++) { for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { d[i][j] = min(d[i][j], d[i][k] + d[k][j]); } } } } int main() { CreateGraph(); Dijkstra(1); // 求从起点 1 到其他所有点的最短距离 for (int i = 1; i <= n; i++) { cout << dist[i] << ' '; } cout << endl; FloydWarshall(); // 求任意两点间的最短距离 for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { cout << d[i][j] << ' '; } cout << endl; } return 0; } ``` 以上是一个简单的实现,你可以根据自己的需要进行修改和优化。希望能够帮到你!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值