FloydWarshall多(所有)源点的最短路径实现(带路径打印)
一、介绍和算法原理:
https://www.cs.usfca.edu/~galles/visualization/Floyd.html
二、核心代码:
dist[i][j]
表示从i
到j
的最短距离,parent[i][j]
表示源点为i
时,j
的双亲是谁,一开始我都初始化parent[i][j] = i
下面的是这个算法的核心代码,书上讲的挺好的,dist
(k)
[i][j]
表示从i
到j
,中间由序号不大于k
的顶点序号(可能是多个)作为中转点时,i
与j
的最短路径。
for(int k = 0; k < V; k++){for(int i = 0; i < V; i++){for(int j = 0; j < V; j++){if(dist[i][k] + dist[k][j] < dist[i][j]){dist[i][j] = dist[i][k] + dist[k][j]; parents[i][j] = parents[k][j]; }}}}
1. 这里外循环k=0
,里面两层循环尝试更新所有i-->j
以k=0
为中间节点时的最短距离。可能会出现这些情况,1-->0-->5
,2-->0-->3
,3-->0-->1
,(0-->0-->5
这种就没意义)
2. 当k=1
时,尝试所有i->1->j
路径,因为上一步k=0
的时候检查过1->0->(0,1,2...n-1)
会不会让1
到其他各点的距离会不会变短,所以这个i->1->j
是在上一步的基础上的,即2-->1--->5
可能代表的这条路径2-->1-->0-->5
,3-->1--->4
可能代表的这条路径3-->1-->0-->4
,当然0-->1--->4
也是可能的。
3. k=2
时,尝试以2
为中间点(事实上是尝试把2
加到中间点序列),即0-->2-->5
可能代表着0-->1-->2-->5
,3-->2-->6
可能代表着3-->1-->2-->0---->6
,但是不会出现3-->5--->1--->6
这种情况,因为5
还没做为中间结点去检查过。
4…
5…
…
在内外循环结束之后,所有结点都尝试被当做中间结点加入i
与j
的路径中去了,所以得到dist[i][j]
就i
到j
的最短路径了。
二、全部代码:
#include<iostream>
#include<vector>using namespace std;#define INF 999999 //不可能的权值
#define V 6 //顶点数
void printSolution(int dist[][V],int parents[][V],int graph[][V])
{cout<<"打印任一对顶点间的最短路径,"<<"若weight为INF和dist[i][j]为INF则表示i->j无路径"<<endl; for(int i = 0; i < V; i++){cout<<"------从"<<i<<"出发到各顶点的最短路径:-------"<<endl; for(int j = 0; j < V; j++){cout<<parents[i][j]<<" --> "<<j<<" \t weight is :";int parent = parents[i][j];if (graph[parent][j] == INF) cout<<"INF"<<" "; elsecout<<graph[parent][j]<<" ";cout<<" dist["<<i<<"]["<<j<<"] is ";if (dist[i][j] == INF) cout<<"INF"<<endl; elsecout<<dist[i][j]<<endl; }cout<<endl;}
}
void floydWarshall(int graph[][V])
{int dist[V][V]; int parents[V][V]; //parent[i][0...V-1]是从第i个元素//出发的双亲数组,用来记录路径 for(int i = 0; i < V; i++){for(int j = 0; j < V; j++){dist[i][j] = graph[i][j];//从i出发时将i视为其他顶点的双亲,若后面变了,说明加了中转顶点 parents[i][j] = i; } }for(int k = 0; k < V; k++){for(int i = 0; i < V; i++){for(int j = 0; j < V; j++){if(dist[i][k] + dist[k][j] < dist[i][j]){dist[i][j] = dist[i][k] + dist[k][j]; parents[i][j] = parents[k][j]; }}}}printSolution(dist,parents,graph);
}
int main()
{int graph[V][V] = { {0, INF, 10, INF, 30, 100}, {INF, 0, 5, INF, INF, INF}, {INF, INF, 0, 50, INF, 1}, {INF, INF, INF, 0, INF, 10}, {INF, INF, INF, 20, 0, 60},{INF, INF, INF, 0, INF, 0}, }; floydWarshall(graph);return 0;
}
输出:
打印任一对顶点间的最短路径,若weight为INF和dist[i][j]为INF则表示i->j无路径
------从0出发到各顶点的最短路径:-------
0 --> 0 weight is :0 dist[0][0] is 0
0 --> 1 weight is :INF dist[0][1] is INF
0 --> 2 weight is :10 dist[0][2] is 10
5 --> 3 weight is :0 dist[0][3] is 11
0 --> 4 weight is :30 dist[0][4] is 30
2 --> 5 weight is :1 dist[0][5] is 11------从1出发到各顶点的最短路径:-------
1 --> 0 weight is :INF dist[1][0] is INF
1 --> 1 weight is :0 dist[1][1] is 0
1 --> 2 weight is :5 dist[1][2] is 5
5 --> 3 weight is :0 dist[1][3] is 6
1 --> 4 weight is :INF dist[1][4] is INF
2 --> 5 weight is :1 dist[1][5] is 6------从2出发到各顶点的最短路径:-------
2 --> 0 weight is :INF dist[2][0] is INF
2 --> 1 weight is :INF dist[2][1] is INF
2 --> 2 weight is :0 dist[2][2] is 0
5 --> 3 weight is :0 dist[2][3] is 1
2 --> 4 weight is :INF dist[2][4] is INF
2 --> 5 weight is :1 dist[2][5] is 1------从3出发到各顶点的最短路径:-------
3 --> 0 weight is :INF dist[3][0] is INF
3 --> 1 weight is :INF dist[3][1] is INF
3 --> 2 weight is :INF dist[3][2] is INF
3 --> 3 weight is :0 dist[3][3] is 0
3 --> 4 weight is :INF dist[3][4] is INF
3 --> 5 weight is :10 dist[3][5] is 10------从4出发到各顶点的最短路径:-------
4 --> 0 weight is :INF dist[4][0] is INF
4 --> 1 weight is :INF dist[4][1] is INF
4 --> 2 weight is :INF dist[4][2] is INF
4 --> 3 weight is :20 dist[4][3] is 20
4 --> 4 weight is :0 dist[4][4] is 0
3 --> 5 weight is :10 dist[4][5] is 30------从5出发到各顶点的最短路径:-------
5 --> 0 weight is :INF dist[5][0] is INF
5 --> 1 weight is :INF dist[5][1] is INF
5 --> 2 weight is :INF dist[5][2] is INF
5 --> 3 weight is :0 dist[5][3] is 0
5 --> 4 weight is :INF dist[5][4] is INF
5 --> 5 weight is :0 dist[5][5] is 0--------------------------------
Process exited with return value 0
Press any key to continue . . .
FloydWarshall多(所有)源点的最短路径实现(带路径打印)相关推荐
- Bellman_Ford边上权值为任意值的单源最短路径问题(+路径打印)边集合与邻接表两种实现
一.介绍: https://en.wikipedia.org/wiki/Bellman%E2%80%93Ford_algorithm 二.维基上的伪代码: function BellmanFord(l ...
- Warshall算法多源点之间最短路径的算法最短距离
简介:Floyd算法又称为插点法,是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法,与Dijkstra算法类似.该算法名称以创始人之一.1978年图灵奖获得者.斯坦福大学计算机科学系 ...
- 【PAT数据结构与算法题目集】 旅游规划(单源最短路径,长度+路径查找)
[PAT数据结构与算法题目集] 旅游规划(单源最短路径,长度+路径查找) 题目 有了一张自驾旅游路线图,你会知道城市间的高速公路长度.以及该公路要收取的过路费.现在需要你写一个程序,帮助前来咨询的游客 ...
- 带条码打印的固定资产管理系统源码
带条码打印的固定资产管理系统源码 本源码亲测可用! 功能介绍 1.基本信息管理:包括资产分类,基本资料,资产编号规则,保存列间距和选择资产显示列等功能: 2.固定资产管理:包括资产增加,资产更新,资产 ...
- C# winform源码下载 带条码打印的固定资产管理系统源码 VS2010
C# winform源码下载 带条码打印的固定资产管理系统源码 VS2010下载链接:https://pan.baidu.com/s/1SJAYrO72FOEY-Wbq3Sgurg 提取码:85x6
- window自带print打印设置
window自带一个打印方法 print(): 默认打印页面中body里的所有内容 1,给打印按钮绑定一个οnclick="print()'' 方法: 在script里写上这个方法 func ...
- python 判断带路径的文件是否存在,否则创建
#先在网络上没有找到,所以自己动手写出来,如果各位大牛在某处找到类似的例子,请不要吐槽,谢谢! import os #先定义一个带路径的文件 filename = "/home/mydir/ ...
- 用python写自动化测试脚本常用功能:结果记录,运行日志,测试配置,带颜色打印在控制台
用python写自动化测试脚本常用功能:结果记录,运行日志,测试配置,带颜色打印在控制台 利用csv库来记录测试结果 利用logging库来记录脚本运行信息 利用ConfigParser库来读取测试配 ...
- dijkstra--非负权值的单源最短路径STL实现(邻接表+优先队列) (带路径)
一.预备知识: 用优先队列做大小根堆 注意:是非负权值的单源最短路径的STL实现,权值是负的不能用dijkstra算法 解释在第一段 二.代码: #include<iostream> #i ...
最新文章
- 利用dom4j将实体类转换为对应的xml报文
- Retrofit2.0
- Codeforces791:Ordinary Numbers题解
- 实践:基于深度学习的卫星图像超分辨率处理技术(一)
- 暑期训练日志----2018.8.10
- 那些除夕夜还在上BOSS直聘的人
- Java 线程第三版 第八章 Thread与Collection Class 读书笔记
- 性能测试--jmeter中正则表达式提取器的使用【16】
- jQuery倒计时进度条
- 什么是 ODBC – 开放式数据库连接
- shiny app制作基本思路
- spring-kafka源码解析
- Ubuntu20.04更换阿里源教程
- .doc文件不显示word图标的解决方法
- MacOS 开启latex人生(mactex+texmaker安装)
- 企业网站用什么服务器操作系统?
- shields 徽标_创意讲故事徽标的剖析
- 验证网站代码的免费在线工具
- PHP - strtotime()的慎用
- 自媒体搞笑领域怎么做?这几个类型都很热门,可以尝试