声明:图片及内容基于https://www.bilibili.com/video/BV1oa4y1e7Qt?from=articleDetail

多源最短路径的引入

Floyd算法

原理

加入a:

加入b:

加入c:

数据结构

核心代码

Floyd()

  1. void MGraph::Floyd(){
  2. for(int i=0;i<vertexNum;i++){
  3. for(int j=0;j<vertexNum;j++){
  4. dist[i][j]=arc[i][j]; //dist数组初始化
  5. if(dist[i][j]!=INFINIT&&dist[i][j]!=0) //dist为INFINIT则无路径,dist为0则指向自己
  6. path[i][j]=vertex[i]+vertex[j]; //path数组初始化
  7. else
  8. path[i][j]=""; //不符合则path为空串
  9. }
  10. }
  11. for(int k=0;k<vertexNum;k++){ //k个顶点循环k次
  12. for(int i=0;i<vertexNum;i++){ //k每循环一次,要更新dist和path数组
  13. for(int j=0;j<vertexNum;j++){
  14. if(dist[i][k]+dist[k][j]<dist[i][j]){
  15. dist[i][j]=dist[i][k]+dist[k][j];
  16. //这里两个path拼接的时候,第一个字符串的最后一个字符和第二个字符串的第一个字符重复
  17. //用substr去除第一个字符串的最后一个字符
  18. string tmp=path[i][k].substr(0,path[i][k].length()-1);
  19. path[i][j]=tmp+path[k][j];
  20. }
  21. }
  22. }
  23. }
  24. displayDist();
  25. displayPath();
  26. }

完整代码

  1. #include<iostream>
  2. #define MAX 50
  3. #define INFINIT 65535
  4. #include <string>
  5. using namespace std;
  6. class MGraph{
  7. private:
  8. int vertexNum,arcNum; //顶点数,边数
  9. int arc[MAX][MAX]; //邻接矩阵
  10. string vertex[MAX]; //顶点信息
  11. int dist[MAX][MAX];
  12. string path[MAX][MAX];
  13. public:
  14. MGraph(string v[],int n,int e);
  15. void display();
  16. void Floyd();
  17. void displayDist();
  18. void displayPath();
  19. };
  20. void MGraph::Floyd(){
  21. for(int i=0;i<vertexNum;i++){
  22. for(int j=0;j<vertexNum;j++){
  23. dist[i][j]=arc[i][j]; //dist数组初始化
  24. if(dist[i][j]!=INFINIT&&dist[i][j]!=0) //dist为INFINIT则无路径,dist为0则指向自己
  25. path[i][j]=vertex[i]+vertex[j]; //path数组初始化
  26. else
  27. path[i][j]=""; //不符合则path为空串
  28. }
  29. }
  30. for(int k=0;k<vertexNum;k++){ //k个顶点循环k次
  31. for(int i=0;i<vertexNum;i++){ //k每循环一次,要更新dist和path数组
  32. for(int j=0;j<vertexNum;j++){
  33. if(dist[i][k]+dist[k][j]<dist[i][j]){
  34. dist[i][j]=dist[i][k]+dist[k][j];
  35. //这里两个path拼接的时候,第一个字符串的最后一个字符和第二个字符串的第一个字符重复
  36. //用substr去除第一个字符串的最后一个字符
  37. string tmp=path[i][k].substr(0,path[i][k].length()-1);
  38. path[i][j]=tmp+path[k][j];
  39. }
  40. }
  41. }
  42. }
  43. displayDist();
  44. displayPath();
  45. }
  46. void MGraph::displayDist(){ //打印dist数组
  47. cout<<"dist数组:"<<endl;
  48. for(int i=0;i<vertexNum;i++){
  49. for(int j=0;j<vertexNum;j++){
  50. cout<<dist[i][j]<<"\t";
  51. }
  52. cout<<endl;
  53. }
  54. }
  55. void MGraph::displayPath(){ //打印path数组
  56. cout<<"path数组:" <<endl;
  57. for(int i=0;i<vertexNum;i++){
  58. for(int j=0;j<vertexNum;j++){
  59. cout<<path[i][j]<<"\t";
  60. }
  61. cout<<endl;
  62. }
  63. }
  64. MGraph::MGraph(string v[],int n,int e){ //n是顶点数,e是边数
  65. vertexNum=n;
  66. arcNum=e;
  67. for(int i=0;i<vertexNum;i++){
  68. vertex[i]=v[i];
  69. }
  70. for(int i=0;i<arcNum;i++){ //初始化邻接矩阵
  71. for(int j=0;j<arcNum;j++){
  72. if(i==j) arc[i][j]=0;
  73. else arc[i][j]=INFINIT;
  74. }
  75. }
  76. int vi,vj,w;
  77. for(int i=0;i<arcNum;i++){
  78. cout<<"请输入有向边的两个顶点和这条边的权值"<<endl;
  79. cin>>vi>>vj>>w; //输入边依附的两个顶点的编号 和权值
  80. arc[vi][vj]=w; //有边标志
  81. }
  82. }
  83. void MGraph::display(){
  84. cout<<"邻接矩阵:"<<endl;
  85. for(int i=0;i<vertexNum;i++){
  86. for(int j=0;j<vertexNum;j++){
  87. if(arc[i][j]==INFINIT)
  88. cout<<"∞"<<"\t";
  89. else cout<<arc[i][j]<<"\t";
  90. }
  91. cout<<endl;
  92. }
  93. cout<<endl;
  94. cout<<"结点信息:"<<endl;
  95. for(int i=0;i<vertexNum;i++){
  96. cout<<vertex[i]<<" ";
  97. }
  98. cout<<endl;
  99. }
  100. int main(){
  101. int n,e;
  102. string v[MAX];
  103. cout<<"请输入顶点数和边数"<<endl;
  104. cin>>n>>e;
  105. cout<<"请输入顶点信息"<<endl;
  106. for(int i=0;i<n;i++){
  107. cin>>v[i];
  108. }
  109. MGraph mgraph(v,n,e);
  110. mgraph.display();
  111. mgraph.Floyd();
  112. return 0;
  113. }

输入:

3 5
a b c
0 1 4
0 2 11
1 0 6
1 2 2
2 0 3

输出:

邻接矩阵:
0 4 11
6 0 2
3 ∞ 0

结点信息:
a b c
dist数组:
0 4 6
5 0 2
3 7 0
path数组:
   ab   abc
bca       bc
ca   cab

例题:娱乐中心选址

  1. #include<iostream>
  2. #define MAX 50
  3. #define INFINIT 65535
  4. #include <string>
  5. using namespace std;
  6. class MGraph{
  7. private:
  8. int vertexNum,arcNum; //顶点数,边数
  9. int arc[MAX][MAX]; //邻接矩阵
  10. string vertex[MAX]; //顶点信息
  11. int dist[MAX][MAX];
  12. string path[MAX][MAX];
  13. int rowSum[MAX];
  14. int rowMax[MAX];
  15. public:
  16. MGraph(string v[],int n,int e);
  17. void display();
  18. void Floyd();
  19. void displayDist();
  20. void displayPath();
  21. void bestCentralAmusement();
  22. void displayRowMax();
  23. void displayRowSum();
  24. };
  25. void MGraph::bestCentralAmusement(){
  26. for(int i=0;i<vertexNum;i++)
  27. rowSum[i]=0;
  28. for(int i=0;i<vertexNum;i++){
  29. for(int j=0;j<vertexNum;j++){
  30. rowSum[i]+=dist[i][j];
  31. }
  32. }
  33. int tmp;
  34. for(int i=0;i<vertexNum;i++){
  35. tmp=0;
  36. for(int j=0;j<vertexNum;j++){
  37. if(tmp<dist[i][j]) tmp=dist[i][j];
  38. }
  39. rowMax[i]=tmp;
  40. }
  41. int tmp2=INFINIT;
  42. int index=-1;
  43. for(int i=0;i<vertexNum;i++){
  44. if(rowMax[i]<tmp2){
  45. tmp2=rowMax[i];
  46. index=i;
  47. }
  48. if(tmp2==rowMax[i]){
  49. if(rowSum[i]<tmp2){
  50. index=i;
  51. }else{
  52. ;
  53. }
  54. }
  55. }
  56. displayRowMax();
  57. displayRowSum();
  58. cout<<"index:"<<index<<endl;
  59. cout<<"最合适的位置是"<<vertex[index]<<endl;
  60. }
  61. void MGraph::displayRowSum(){
  62. cout<<"rowSum: "<<endl;
  63. for(int i=0;i<vertexNum;i++)
  64. cout<<rowSum[i]<<" ";
  65. cout<<endl;
  66. }
  67. void MGraph::displayRowMax(){
  68. cout<<"rowMax:"<<endl;
  69. for(int j=0;j<vertexNum;j++)
  70. cout<<rowMax[j]<<" ";
  71. cout<<endl;
  72. }
  73. void MGraph::Floyd(){
  74. for(int i=0;i<vertexNum;i++){
  75. for(int j=0;j<vertexNum;j++){
  76. dist[i][j]=arc[i][j]; //dist数组初始化
  77. if(dist[i][j]!=INFINIT&&dist[i][j]!=0) //dist为INFINIT则无路径,dist为0则指向自己
  78. path[i][j]=vertex[i]+vertex[j]; //path数组初始化
  79. else
  80. path[i][j]=""; //不符合则path为空串
  81. }
  82. }
  83. for(int k=0;k<vertexNum;k++){ //k个顶点循环k次
  84. for(int i=0;i<vertexNum;i++){ //k每循环一次,要更新dist和path数组
  85. for(int j=0;j<vertexNum;j++){
  86. if(dist[i][k]+dist[k][j]<dist[i][j]){
  87. dist[i][j]=dist[i][k]+dist[k][j];
  88. //这里两个path拼接的时候,第一个字符串的最后一个字符和第二个字符串的第一个字符重复
  89. //用substr去除第一个字符串的最后一个字符
  90. string tmp=path[i][k].substr(0,path[i][k].length()-1);
  91. path[i][j]=tmp+path[k][j];
  92. }
  93. }
  94. }
  95. }
  96. displayDist();
  97. displayPath();
  98. }
  99. void MGraph::displayDist(){ //打印dist数组
  100. cout<<"dist数组:"<<endl;
  101. for(int i=0;i<vertexNum;i++){
  102. for(int j=0;j<vertexNum;j++){
  103. cout<<dist[i][j]<<"\t";
  104. }
  105. cout<<endl;
  106. }
  107. }
  108. void MGraph::displayPath(){ //打印path数组
  109. cout<<"path数组:" <<endl;
  110. for(int i=0;i<vertexNum;i++){
  111. for(int j=0;j<vertexNum;j++){
  112. cout<<path[i][j]<<"\t";
  113. }
  114. cout<<endl;
  115. }
  116. }
  117. MGraph::MGraph(string v[],int n,int e){ //n是顶点数,e是边数
  118. vertexNum=n;
  119. arcNum=e;
  120. for(int i=0;i<vertexNum;i++){
  121. vertex[i]=v[i];
  122. }
  123. for(int i=0;i<arcNum;i++){ //初始化邻接矩阵
  124. for(int j=0;j<arcNum;j++){
  125. if(i==j) arc[i][j]=0;
  126. else arc[i][j]=INFINIT;
  127. }
  128. }
  129. int vi,vj,w;
  130. for(int i=0;i<arcNum;i++){
  131. cout<<"请输入有向边的两个顶点和这条边的权值"<<endl;
  132. cin>>vi>>vj>>w; //输入边依附的两个顶点的编号 和权值
  133. arc[vi][vj]=w; //有边标志
  134. }
  135. }
  136. void MGraph::display(){
  137. cout<<"邻接矩阵:"<<endl;
  138. for(int i=0;i<vertexNum;i++){
  139. for(int j=0;j<vertexNum;j++){
  140. if(arc[i][j]==INFINIT)
  141. cout<<"∞"<<"\t";
  142. else cout<<arc[i][j]<<"\t";
  143. }
  144. cout<<endl;
  145. }
  146. cout<<endl;
  147. cout<<"结点信息:"<<endl;
  148. for(int i=0;i<vertexNum;i++){
  149. cout<<vertex[i]<<" ";
  150. }
  151. cout<<endl;
  152. }
  153. int main(){
  154. int n,e;
  155. string v[MAX];
  156. cout<<"请输入顶点数和边数"<<endl;
  157. cin>>n>>e;
  158. cout<<"请输入顶点信息"<<endl;
  159. for(int i=0;i<n;i++){
  160. cin>>v[i];
  161. }
  162. MGraph mgraph(v,n,e);
  163. mgraph.display();
  164. mgraph.Floyd();
  165. mgraph.bestCentralAmusement();
  166. return 0;
  167. }

输入:

5 10
a b c d e
0 1 13
0 3 4
1 0 13
1 2 15
1 4 5
2 3 12
3 0 4
3 2 12
4 2 6
4 3 3

输出:

邻接矩阵:
0   13 ∞  4  ∞
13  0 15 ∞  5
∞  ∞  0  12 ∞
4  ∞  12  0  ∞
∞  ∞  6   3  0

结点信息:
a b c d e
dist数组:
0  13  16  4 18
12  0  11  8  5
16 29  0 12 34
4  17  12 0  22
7  20   6  3  0
path数组:
ab adc ad abe
beda bec bed be
cda cdab cd cdabe
da dab dc dabe
eda edab ec ed
rowMax:
18 12 34 22 20
rowSum:
51 36 91 55 36
index:1
最合适的位置是b

最短路径(Floyd算法)的更多相关文章

  1. 单源最短路径Dijkstra算法,多源最短路径Floyd算法

    1.单源最短路径 (1)无权图的单源最短路径 /*无权单源最短路径*/ void UnWeighted(LGraph Graph, Vertex S) { std::queue<Vertex&g ...

  2. 7-8 哈利·波特的考试(25 分)(图的最短路径Floyd算法)

    7-8 哈利·波特的考试(25 分) 哈利·波特要考试了,他需要你的帮助.这门课学的是用魔咒将一种动物变成另一种动物的本事.例如将猫变成老鼠的魔咒是haha,将老鼠变成鱼的魔咒是hehe等等.反方向变 ...

  3. 最短路径(Floyd)算法

    #include <stdio.h>#include <stdlib.h>/* Floyd算法 */#define VNUM 5#define MV 65536int P[VN ...

  4. 单源最短路径——Floyd算法

    正如我们所知道的,Floyd算法用于求最短路径.Floyd算法可以说是Warshall算法的扩展,三个for循环就可以解决问题,所以它的时间复杂度为O(n^3). Floyd算法的基本思想如下:从任意 ...

  5. 最短路径Floyd算法【图文详解】

    Floyd算法 1.定义概览 Floyd-Warshall算法(Floyd-Warshall algorithm)是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权的最短路径问题,同时也被 ...

  6. 【最短路径Floyd算法详解推导过程】看完这篇,你还能不懂Floyd算法?还不会?

    简介 Floyd-Warshall算法(Floyd-Warshall algorithm),是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法,与Dijkstra算法类似.该算法名称以 ...

  7. 图论之最短路径floyd算法

    Floyd算法是图论中经典的多源最短路径算法,即求任意两点之间的最短路径. 它可采用动态规划思想,因为它满足最优子结构性质,即最短路径序列的子序列也是最短路径. 举例说明最优子结构性质,上图中1号到5 ...

  8. 最短路径—Floyd算法

    Floyd算法 所有顶点对之间的最短路径问题是:对于给定的有向网络G=(V,E),要对G中任意两个顶点v,w(v不等于w),找出v到w的最短路径.当然我们可以n次执行DIJKSTRA算法,用FLOYD ...

  9. 最短路径——Floyd算法(含证明)

    通过dij,ford,spfa等算法可以快速的得到单源点的最短路径,如果想要得到图中任意两点之间的最短路径,当然可以选择做n遍的dij或是ford,但还有一个思维量较小的选择,就是floyd算法. 多 ...

  10. 多源最短路径Floyd算法

    多源最短路径是求图中任意两点间的最短路,采用动态规划算法,也称为Floyd算法.将顶点编号为0,1,2...n-1首先定义dis[i][j][k]为顶点 i 到 j 的最短路径,且这条路径只经过最大编 ...

随机推荐

  1. UIKit and SwiftUI

    UIKit and SwiftUI Live Preview Try Again or Resume refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许 ...

  2. flutter package & pub publish

    flutter package & pub publish dart-library-package https://pub.dev/packages/dart_library_package ...

  3. Flutter & release an iOS app

    Flutter & release an iOS app https://flutter.dev/docs/deployment/ios .ipa https://en.wikipedia.o ...

  4. c++ 获取和设置 窗口标题

    有些窗口标题中含有中文,可能识别不出来,可以改一下 SetWindowTextW GetWindowTextW 设置: SetWindowTextW( (HWND)0x00370868/*窗口句柄*/ ...

  5. gitLab的使用 和 git 、 github、gitlab的区别

    一.git . github.gitlab的区别  (百度相关内容得到的理解) ​ ​ 二.git最基本作用:版本控制 ​ 三.有集成了git的GIT安装包 github和gitlab都使用git该版 ...

  6. Python算法_递归:汉诺塔

    游戏链接:https://zhangxiaoleiv.github.io/app/TowerOfHanoi/Hanoi.html 汉诺塔游戏算法: 1 def hanoi(n,x,y,z): 2 if ...

  7. Byte Buddy学习笔记

    本文转载自Byte Buddy学习笔记 简介 Byte Buddy是一个JVM的运行时代码生成器,你可以利用它创建任何类,且不像JDK动态代理那样强制实现一个接口.Byte Buddy还提供了简单的A ...

  8. 1094 The Largest Generation ——PAT甲级真题

    1094 The Largest Generation A family hierarchy is usually presented by a pedigree tree where all the ...

  9. 鸿蒙的js开发部模式16:鸿蒙布局Grid网格布局的应用一

    鸿蒙入门指南,小白速来!从萌新到高手,怎样快速掌握鸿蒙开发?[课程入口]目录:1.Grid简介2.使用Grid布局实现的效果3.grid-row-gap和grid-colunm-gap属性4.< ...

  10. Information:java: javacTask: 源发行版 8 需要目标发行版 1.8

    原文链接:https://blog.csdn.net/idiot_qi/article/details/105149846 创建新maven项目跑main,出现这个编译异常 网上找了找,记录一下以备不 ...