Floyd算法求多源汇最短路

说明:CSDN和公众号文章同步发布,需要第一时间收到最新内容,请关注公众号【比特正传】。

在我国两弹一星事业起步初期,钱学森先生就提出:【先仿制,后改进,再设计】,学习算法亦是如此,尤其是模板题,先模仿写,等熟练了可以考虑该算法是否可以继续优化(SPFA算法就是西南交通大学 段凡丁教授基于Bellman-ford做的改进),最后可以设计自己的算法解决某类问题。

之前的图论合集文章中讲了最短路、拓扑排序、最小生成树等算法,文章链接如下:

图论第二讲:Dijkstra求最短路

图论第三讲:Bellman-ford与SPFA求最短路

图论第四讲:拓扑排序

图论第五讲:Kruskal算法求最小生成树

之前提到的Dijkstra、Bellman-ford和SPFA求最短路,是单源最短路,即求解从某一个点出发到其他点的最短距离,那么多源汇最短路怎么办呢?可以通过Floyd(弗洛伊德)算法进行求解。

1、问题描述

题目链接:

https://www.luogu.com.cn/problem/B3647

图片

本题需求解任意两点间的最短路,使用Floyd算法来完成。

2、算法思想和步骤

初始化dist[i][j]为节点i到结点j的距离,那么dist[i][j]=0,节点到节点自己的距离肯定为0,其次,如果i和j相连,那么初始值为两节点边的权值,dist[i][j]=w,否则均为无穷大INF。

Floyd算法步骤很简单,简单粗暴的三层循环,第一层循环遍历中间节点k,第二层循环遍历起点i,第三层循环遍历终点j,目的是从节点i走到节点j,如果可以通过i走到k,然后从k走到j,且这种方式的权值更小,那么更新dist[i][j] = dist[i][k] + dist[k][j]。

步骤很简单,代码写起来也很简单,Floyd也是模板代码,需要每位同学熟练编写。

3、编写code

#include<bits/stdc++.h>
using namespace std;
const int N = 105, INF = 0x3f3f3f3f;
int n, m, u, v, w, dist[N][N];
void init() {
  for(int i=1; i<=n; i++) {
    for(int j=1; j<=n; j++) {
      if(i == j) dist[i][j] = 0;  // 到自己的距离为0 
      else dist[i][j] = INF;  // 否则先初始化为"无穷大" 
    }
  }
}
void floyd() {  // Floyd算法的模板代码,需要熟练编写 
  for(int k=1; k<=n; k++) {
    for(int i=1; i<=n; i++) {
      for(int j=1; j<=n; j++) {
        dist[i][j] = min(dist[i][j], dist[i][k]+dist[k][j]);  // 更新结点i到节点j的权值 
      }
    }
  }
  return;
}
void printAns() {
  for(int i=1; i<=n; i++) {
    for(int j=1; j<=n; j++) {
      cout << dist[i][j] << " ";
    }
    cout << "\n";
  }
}
int main() {
  cin >> n >> m;
  init();
  for(int i=1; i<=m; i++) {
    cin >> u >> v >> w;
    dist[u][v] = min(w, dist[u][v]);
    dist[v][u] = min(w, dist[v][u]);
  }
  floyd();
  printAns();  // 按照题目要求输出结果 
  return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值