[图] Floyd算法|佛洛依德 - 任意两点的最短路径 - C语言实现
文章目录
- 原理
- 核心代码
- 代码
- path[][]数组解释
- 完整代码
原文链接:https://www.yuque.com/cppdev/algo/bgt4ea
原理
【Floyd算法】用动态规划的思想求任意两点之间的最短路径
【评价】时间复杂度O(n3)O(n^3)O(n3),空间复杂度O(n2)O(n^2)O(n2),但形式上比Dijkstra简单些,也容易理解
【基本思想】以二维数组D[v][w]保存v->w的最短路径长度
- 【初始状态】D[v][w] --> 没有中间点,v直接走到w的距离
- 【分别考虑所有结点u】把u看成中转站,检查v->u->w(即D[v][u]+D[u][w])是否比v->w(即D[v][w])小,如果小就更新D[v][w]的值
【当然】我们还需要一个path[v][w]的二维数组来保存路径(path[][]详细解释请看下文)
【主要公式】
// D[v][w]存储v->w的最短路径长度
// v->w中间可能经过很多点
if (D[v][u] + D[u][w] < D[v][w]) { // v->u->w的长度 < 当前v->w的长度D[v][w] = D[v][u] + D[u][v]; //那么最短路径D[v][w]即是 v->u->w的距离path[i][j] = v; //i->j的路径上,有中转站v
}
【算法示例】
核心代码
void PrintPath(int u, int v, int path[][maxSize]) {int mid;if (path[u][v]==-1) {//直接输出,没有中间点printf("<%c,%c> ", vertexs[u], vertexs[v]);} else { //有中间点mid = path[u][v];PrintPath(u, mid, path);PrintPath(mid, v, path);}
}
void Floyd(int n, int MGraph[][maxSize], int path[][maxSize]) {int i,j,v;int A[maxSize][maxSize]; //最短路径//初始化:A-1没有考虑中间节点for (i=0; i<n; ++i) {for (j=0; j<n; j++) {A[i][j] = MGraph[i][j];path[i][j] = -1;}}//循环考虑中间节点for (v=0; v<n; ++v) {for (i=0; i<n; ++i) {for (j=0; j<n; ++j) {if (A[i][j]>A[i][v]+A[v][j]) {A[i][j] = A[i][v] + A[v][j];path[i][j] = v;}}}}
}
代码
测试数据 | 结果 | 0->3的最短路径 |
---|---|---|
0到3的最短路径为0->5->4->3 ,即A->F->E->D
|
path[][]数组解释
结点 | A | B | C | D | E | F | G | |
---|---|---|---|---|---|---|---|---|
下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | |
A | 0 | 1 | -1 | 1 | 5 | 5 | -1 | -1 |
B | 1 | -1 | -1 | 2 | -1 | 2 | 3 | 6 |
C | 2 | 1 | -1 | 1 | -1 | 3 | 4 | 1 |
D | 3 | 5 | 2 | -1 | 4 | -1 | 4 | -1 |
E | 4 | 5 | 3 | 3 | -1 | 5 | -1 | 5 |
F | 5 | -1 | 6 | 4 | 4 | -1 | 4 | -1 |
G | 6 | -1 | -1 | 1 | -1 | 5 | -1 | 3 |
【path[u][v]的值】u->v的最短路径中,有中转站path[u][v]
【特殊值】path[u][v]=-1:表示u到v之间没有中间节点–>u到v的最短路径即是边u->v
【求法】求0到3的最短路径
path[0][5]=5 --> 0到3的路上有中转站5
,即0->5->3
- 【0->5->3前半段】
path[0][5]=1 --> 0到5的路上没有中转站了
,前半段即0->5
- 【0->5->3后半段】
path[5][3]=4 --> 5到3的路上有中转站4
,后半段5->4->3
- 【5->4->3前半段】
path[5][4]=-1 --> 没有中转站了
,即5->4
- 【5->4->3后半段】
path[4][3]=-1 --> 没有中转站
,即4->3
- 【5->4->3前半段】
【综上】0到3的最短路径为0->5->4->3
,即A->F->E->D
完整代码
#include<stdio.h>
#include<stdlib.h>#define maxSize 10
#define INF 100int MGraph[maxSize][maxSize]; //邻接矩阵
char vertexs[maxSize]; //结点信息void PrintPath(int u, int v, int path[][maxSize]) {int mid;if (path[u][v]==-1) {//直接输出,没有中间点printf("<%c,%c> ", vertexs[u], vertexs[v]);} else { //有中间点mid = path[u][v];PrintPath(u, mid, path);PrintPath(mid, v, path);}
}
void Floyd(int n, int MGraph[][maxSize], int path[][maxSize]) {int i,j,v;int A[maxSize][maxSize]; //最短路径//初始化:A-1没有考虑中间节点for (i=0; i<n; ++i) {for (j=0; j<n; j++) {A[i][j] = MGraph[i][j];path[i][j] = -1;}}//循环考虑中间节点for (v=0; v<n; ++v) {for (i=0; i<n; ++i) {for (j=0; j<n; ++j) {if (A[i][j]>A[i][v]+A[v][j]) {A[i][j] = A[i][v] + A[v][j];path[i][j] = v;}}}}
}int main() {/*
7
ABCDEFG
10000 18 10000 10000 10000 19 18
18 10000 8 10000 10000 10000 20
10000 8 10000 20 10000 10000 10000
10000 10000 20 10000 9 16 15
10000 10000 10000 9 10000 3 10000
19 10000 10000 16 3 10000 15
18 20 10000 15 10000 15 10000
0 2
0 3
0 4
1 6
4 6
3 6
*/int n;int i,j;char tmp[maxSize+5];int path[maxSize][maxSize];int start,end;scanf("%d", &n); //结点数scanf("%s", tmp); //结点信息for (i=0; i<n; i++)vertexs[i] = tmp[i];for (i=0; i<n; i++) { //矩阵for (j=0; j<n; j++) {scanf("%d", &MGraph[i][j]);}}Floyd(n, MGraph, path);//打印path数组printf("- path数组\n");printf("结点");for (i=0; i<n; i++) {printf("\t%c", vertexs[i]);}printf("\n");for (i=0; i<n; i++) {printf("%c\t", vertexs[i]);for (j=0; j<n; j++) {printf("%d\t", path[i][j]);}printf("\n");}//输出最短路径while (1) {printf("\n\n>>> 输入起始点的下标(空格间隔):");scanf("%d %d" , &start, &end); //输入两个测试的顶点,求v->w的最短路径printf("%c->%c最短路径:", vertexs[start], vertexs[end]);PrintPath(start, end, path);}return 0;
}
[图] Floyd算法|佛洛依德 - 任意两点的最短路径 - C语言实现相关推荐
- 推免复习之数据结构与算法 佛洛依德算法
佛洛依德算法算法作为一个经典的求最短路径的算法,思路其实很简单,就是不停地进行"松弛操作",直到全部遍历一遍.那么什么是松弛操作呢?比如说我们的图存在一个邻接矩阵graph中,gr ...
- 动态规划-Floyd Warshall(佛洛依德) algorithm
一.Floyd算法简介 Floyd(弗洛伊德)算法相对于Dijkstra算法来说,可以解决多源最短路径问题(即可以从任意一个点到任意一个点),可应用于地图导航走最短路径.为各城市修建最短路径的通信网( ...
- java程序两点之间最短路径算法_java 最短路径算法 如何实现有向 任意两点的最短路径...
展开全部 Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节e68a8462616964757a686964616f31333361316131点的最短路径.主要 ...
- 佛洛依德算法求最短路径(记录路径信息)
佛洛依德算法: 利用D矩阵拿到邻接矩阵中的权值.path矩阵记录两点之间的移动中转点(初始值为起点). 对于邻接矩阵中 i 到 j 点的权值进行比较,若加上一个中转点 k 后的权值小于原本的权值,则对 ...
- 最短路径算法 迪杰斯特拉、佛洛依德和贝尔曼
最短路径算法 迪杰斯特拉算法 佛洛依德算法 迪杰斯特拉算法 迪杰斯特拉算法用来解决在有向有权图中某一个点到任意一点的最短路径问题. 注意:只能用来解决权为非零的情况,不能够解决权为负数的情况 思想:我 ...
- 最短路径算法之迪杰斯特拉算法(Dijkstra)和佛洛依德算法(Floyd)
今天学习了这两种算法,都是用来求最小路径的算法,但是迪杰斯特拉算法只能从某个特定点到所有点的最短路径,而佛洛依德算法可以查出任意点到任意点的最小路径. 迪杰斯特拉: package dijkstra; ...
- Java实现佛洛依德算法(floyd)的完整代码
Java实现佛洛依德算法(floyd)的完整代码 /*** 弗洛伊德(floyd)算法求图中所有点对之间的最短路径:* 其中'-1'表示两点之间目前还没有联通的路径:* 结论:如果A点到G点之间有最短 ...
- 佛洛依德算法的学习与实现
1.问题引入 带权有向图中单源点的最短路径问题可以用地杰斯特拉算法求解,如果要求解图中每一对顶点之间的最短路径,类似可以想到的方法为:每次以一个顶点为源点,重复执行地杰斯特拉算法算法n次,这样,便可以 ...
- 十大常用算法之佛洛依德算法
十大常用算法的完整实现 一.二分查找算法:https://blog.csdn.net/weixin_46635575/article/details/121532149 二.分治算法:https:// ...
最新文章
- python算术运算_Python 的二元算术运算详解
- fputc会覆盖吗_墨粉寿命和打印的文件有关系吗?
- mac 串口调试工具_MACamp;串口调试
- 华为提交“NovaBuds”商标申请:nova要出耳机了?
- Linux之 find之 ctime,atime,mtime
- 最新如何在CentOS6版本上安装Teamviewer
- matlab 光谱共聚焦,激光共焦显微拉曼光谱分析实验数据处理及谱图解析
- linux下桌面快捷方式无法打开,亲测可用:Linux下桌面快捷方式创建实例
- 如何简单的将中文翻译为英文
- 高情商的人都在这样表现汇报工作
- C语言中的清屏函数(自己编写)
- poi实现word文档转pdf格式
- 双十一到了,当我用Python采集了电商平台所有商品后发现....
- 使用frp端口映射实现内网穿透(SSH、HTTP服务)
- A Co-Memory Network for Multimodal Sentiment Analysis
- pixfllow光流传感器数据获取及悬停程序编写
- Java:XML之JavaSE SAX解析
- 以软件测试的角度测试一支笔,如何测试一支笔.
- HTML5与HTML4的差异对比(1)
- 给图像打上马赛克python实现
热门文章
- Windows2008服务器 搭建域控制器
- 用嵌套循环打印菱形图案
- AsynoTask简介:
- BIMer们请注意:在建模时千万别让问题分析占用太多时间
- 百望云获评“中国大数据独角兽” 数实相融 算启未来
- IIS部署Ftp服务启动报错:除非Microsoft FTP 服务(FTPSVC)正在运行,否则无法启动FTP站点
- 政简网:公务员上岸!为自己拼一次
- android 名称的由来,三星新系统名称曝光:命名为Experience
- !important用法
- msiexec.exe进程介绍及如何修复被丢失的msiexec.exe系统文件