当前位置:   article > 正文

图-弗洛伊德(FloydWarshall)算法详解(含全部代码)_弗洛伊德算法代码

弗洛伊德算法代码

目录

适用条件

基本操作函数

功能实现函数

测试使用图

算法讲解

初始化

迭代

弗洛伊德算法代码

全部代码

实验结果

最短路径算法比较


适用条件

图中可以有负权,但不能有负圈(圈中弧或边的权值之和小于0)

基本操作函数

  • InitGraph(Graph &G)             初始化函数 参数:图G 作用:初始化图的顶点表,邻接矩阵等
  • InsertNode(Graph &G,VexType v) 插入点函数 参数:图G,顶点v 作用:在图G中插入顶点v,即改变顶点表
  • InsertEdge(Graph &G,VexType v,VexType w) 插入弧函数 参数:图G,某弧两端点v和w 作用:在图G两点v,w之间加入弧,即改变邻接矩阵
  • Adjancent(Graph G,VexType v,VexType w) 判断是否存在弧(v,w)函数 参数:图G,某弧两端点v和w 作用:判断是否存在弧(v,w)
  • BFS(Graph G, int start) 广度遍历函数 参数:图G,开始结点下标start 作用:宽度遍历
  • DFS(Graph G, int start) 深度遍历函数(递归形式)参数:图G,开始结点下标start 作用:深度遍历
  • Dijkstra(Graph G, int v)  最短路径 - Dijkstra算法 参数:图G、源点v
  • Bellman_Ford(Graph G, int v)  最短路径 - Bellman_Ford算法  参数:图G、源点v 作用:计算不含负圈图的最短路径 返回是否有圈
  • Floyd_Wallshall(Graph G)    最短路径 - Floyd_Wallshall算法  参数:图G 作用:计算不含负圈图的最短路径 返回是否有圈

功能实现函数

  • CreateGraph(Graph &G) 创建图功能实现函数 参数:图G  InsertNode 作用:创建图
  • BFSTraverse(Graph G)  广度遍历功能实现函数 参数:图G 作用:宽度遍历
  • DFSTraverse(Graph G)  深度遍历功能实现函数 参数:图G 作用:深度遍历
  • Shortest_Dijkstra(Graph &G) 调用最短路径-Dijkstra算法 参数:图G、源点v
  • Shortest_Bellman_Ford(Graph &G) 调用最短路径- - Bellman_Ford算法  参数:图G
  • Shortest_Floyd_Wallshall(Graph &G) 调用最短路径- - Floyd_Wallshall算法  参数:图G

测试使用图

测试使用图

算法讲解

初始化

表格行为i,列为j。D及P后小括号内的值为迭代次数。

D矩阵主对角线为0,其余与邻接矩阵相同。

P矩阵存-1,在输出最短路径时作为递归出口。

迭代

D矩阵的状态转移方程:D(m)[i][j]=min{D(m-1)[i][j],D(m-1)[i][k]+D[k][j]},0<<k<<n-1,其中,m为迭代次数,n为节点个数。

思路:添加一个点Vk,找到Vk的入弧Vi->Vk,再找到Vk的出弧,Vk->Vj,比较D[i][j]与D[i][k]+D[k][j]的大小。

若D矩阵有更新,则对应P矩阵的值为更新处最短路径第一条弧的终点

D(1)

04-3
-30-7
1003
5660

P(1)

-1-1-1-1
-1-1-1-1
-1-1-1-1
-1-1-1-1

 D(2)

04-3
-30-7
1003
5620

加入点V0,V0的入弧有V1->V0与V3->V0,出弧有V0->V1与V0->V2

经比较D(1)[3][2]>D(1)[3][0]+D(1)[0][2],6>5-3=2,所以,将6更新为2。

P(2)

-1-1-1-1
-1-1-1-1
-1-1-1-1
-1-10-1

P(2)[3][2]由P(1)[3][2]改为0,因为最短路径为V3->V0->V2,第一条弧的终点为V0。

D(3)

04-3
-30-7
71003
36-1

0

 加入点V1,V1入弧有V0->V1,V2->V1以及V3->V1,出弧有V1->V2,V1->V0

经比较,D(2)[2][0]>D(2)[2][1]+D(2)[1][0],∞>10-3=7,所以,将∞更新为7。

            D(2)[3][0]>D(1)[3][1]+D(2)[1][0],5>6-3=3,所以,将5更新为3。

            D(2)[3][2]>D(1)[3][1]+D(2)[1][2],2>6-7=-1,所以,将2更新为-1。

P(3)

-1-1-1-1
-1-1-1-1
1-1-1-1
1-11-1

P(3)[2][0]改为1,因为最短路径为V2->V1->V0,第一条弧的终点为V1。

P(3)[3][0]改为1,因为最短路径为V3->V1->V0,第一条弧的终点为V1。

P(3)[3][2]改为1,因为最短路径为V3->V1->V2,第一条弧的终点为V1。

下面的由读者根据原理及矩阵自己补充,加深印象。

D(4)

04-30
-30-7-4
71003
36-1

0

P(4)

-1-1-12
-1-1-12
1-1-1-1
1-11-1

D(5)

04-30
-30-7-4
6903
36-1

0

P(5)

-1-1-12
-1-1-12
33-1-1
1-11-1

注意:弗洛伊德算法的最短路径在输出时不是倒着的,我们记录的是第一条弧的终点。例如,p[2][0]=3,P[3][0]=1,P[1][0]=-1,

则V[2]到V[0]的最短路径为2->3->1->0,值为6。也就是看P矩阵的列,这是与前面两篇最短路径算法不同的地方,需注意。

弗洛伊德算法代码

  1. //最短路径 - Floyd_Wallshall算法 参数:图G 作用:计算不含负圈图的最短路径 返回是否有圈
  2. bool Floyd_Wallshall(Graph G)
  3. {
  4. //初始化
  5. for (int i = 0; i<G.vexnum; i++)
  6. for (int j = 0; j < G.vexnum; j++)
  7. {
  8. if (i == j)F_D[i][j] = 0;
  9. else F_D[i][j] = G.Edge[i][j];
  10. P[i][j] = -1;
  11. }
  12. //初始化结束,开始迭代
  13. for(int k=0;k<G.vexnum;k++)
  14. for (int i = 0; i<G.vexnum; i++)
  15. for (int j = 0; j<G.vexnum; j++)
  16. if (F_D[i][j] > F_D[i][k] + F_D[k][j])
  17. {
  18. F_D[i][j] = F_D[i][k] + F_D[k][j];
  19. P[i][j] = k;
  20. }
  21. bool flag = true;
  22. for (int i = 0; i < G.vexnum; i++)
  23. for (int j = 0; j < G.vexnum; j++)
  24. if (i==j&&F_D[i][j] < 0)
  25. {
  26. flag = false;
  27. break;
  28. }
  29. return flag;
  30. }

全部代码

  1. /*
  2. Project: 图-最短路径-Bellman-Ford算法(可含有负权弧)
  3. Date: 2019/10/24
  4. Author: Frank Yu
  5. 基本操作函数:
  6. InitGraph(Graph &G) 初始化函数 参数:图G 作用:初始化图的顶点表,邻接矩阵等
  7. InsertNode(Graph &G,VexType v) 插入点函数 参数:图G,顶点v 作用:在图G中插入顶点v,即改变顶点表
  8. InsertEdge(Graph &G,VexType v,VexType w) 插入弧函数 参数:图G,某弧两端点v和w 作用:在图G两点v,w之间加入弧,即改变邻接矩阵
  9. Adjancent(Graph G,VexType v,VexType w) 判断是否存在弧(v,w)函数 参数:图G,某弧两端点v和w 作用:判断是否存在弧(v,w)
  10. BFS(Graph G, int start) 广度遍历函数 参数:图G,开始结点下标start 作用:宽度遍历
  11. DFS(Graph G, int start) 深度遍历函数(递归形式)参数:图G,开始结点下标start 作用:深度遍历
  12. Dijkstra(Graph G, int v) 最短路径 - Dijkstra算法 参数:图G、源点v
  13. Bellman_Ford(Graph G, int v) 最短路径 - Bellman_Ford算法 参数:图G、源点v 作用:计算不含负圈图的最短路径 返回是否有圈
  14. Floyd_Wallshall(Graph G) 最短路径 - Floyd_Wallshall算法 参数:图G 作用:计算不含负圈图的最短路径 返回是否有圈
  15. 功能实现函数:
  16. CreateGraph(Graph &G) 创建图功能实现函数 参数:图G InsertNode 作用:创建图
  17. BFSTraverse(Graph G) 广度遍历功能实现函数 参数:图G 作用:宽度遍历
  18. DFSTraverse(Graph G) 深度遍历功能实现函数 参数:图G 作用:深度遍历
  19. Shortest_Dijkstra(Graph &G) 调用最短路径-Dijkstra算法 参数:图G、源点v
  20. Shortest_Bellman_Ford(Graph &G) 调用最短路径- - Bellman_Ford算法 参数:图G
  21. Shortest_Floyd_Wallshall(Graph &G) 调用最短路径- - Floyd_Wallshall算法 参数:图G
  22. */
  23. #include<cstdio>
  24. #include<cstdlib>
  25. #include<cstring>
  26. #include<cmath>
  27. #include<string>
  28. #include<set>
  29. #include<list>
  30. #include<queue>
  31. #include<vector>
  32. #include<map>
  33. #include<iterator>
  34. #include<algorithm>
  35. #include<iostream>
  36. #define MaxVerNum 100 //顶点最大数目值
  37. #define VexType char //顶点数据类型
  38. #define EdgeType int //弧数据类型,有向图时邻接矩阵不对称,有权值时表示权值,没有时1连0不连
  39. #define INF 0x3f3f3f3f//作为最大值
  40. using namespace std;
  41. //图的数据结构
  42. typedef struct Graph
  43. {
  44. VexType Vex[MaxVerNum];//顶点表
  45. EdgeType Edge[MaxVerNum][MaxVerNum];//弧表
  46. int vexnum, arcnum;//顶点数、弧数
  47. }Graph;
  48. //迪杰斯特拉算法全局变量
  49. bool S[MaxVerNum]; //顶点集
  50. int D[MaxVerNum]; //到各个顶点的最短路径
  51. int F_D[MaxVerNum][MaxVerNum];//Floyd的D矩阵 记录最短路径
  52. int Pr[MaxVerNum]; //记录前驱
  53. //*********************************************基本操作函数*****************************************//
  54. //初始化函数 参数:图G 作用:初始化图的顶点表,邻接矩阵等
  55. int P[MaxVerNum][MaxVerNum];//最短路径记录矩阵
  56. void InitGraph(Graph &G)
  57. {
  58. memset(G.Vex, '#', sizeof(G.Vex));//初始化顶点表
  59. //初始化弧表
  60. for (int i = 0; i < MaxVerNum; i++)
  61. for (int j = 0; j < MaxVerNum; j++)
  62. G.Edge[i][j] = INF;
  63. G.arcnum = G.vexnum = 0; //初始化顶点数、弧数
  64. }
  65. //插入点函数 参数:图G,顶点v 作用:在图G中插入顶点v,即改变顶点表
  66. bool InsertNode(Graph &G, VexType v)
  67. {
  68. if (G.vexnum < MaxVerNum)
  69. {
  70. G.Vex[G.vexnum++] = v;
  71. return true;
  72. }
  73. return false;
  74. }
  75. //插入弧函数 参数:图G,某弧两端点v和w 作用:在图G两点v,w之间加入弧,即改变邻接矩阵
  76. bool InsertEdge(Graph &G, VexType v, VexType w, int weight)
  77. {
  78. int p1, p2;//v,w两点下标
  79. p1 = p2 = -1;//初始化
  80. for (int i = 0; i<G.vexnum; i++)//寻找顶点下标
  81. {
  82. if (G.Vex[i] == v)p1 = i;
  83. if (G.Vex[i] == w)p2 = i;
  84. }
  85. if (-1 != p1&&-1 != p2)//两点均可在图中找到
  86. {
  87. G.Edge[p1][p2] = weight;//有向图邻接矩阵不对称
  88. G.arcnum++;
  89. return true;
  90. }
  91. return false;
  92. }
  93. //判断是否存在弧(v,w)函数 参数:图G,某弧两端点v和w 作用:判断是否存在弧(v,w)
  94. bool Adjancent(Graph G, VexType v, VexType w)
  95. {
  96. int p1, p2;//v,w两点下标
  97. p1 = p2 = -1;//初始化
  98. for (int i = 0; i<G.vexnum; i++)//寻找顶点下标
  99. {
  100. if (G.Vex[i] == v)p1 = i;
  101. if (G.Vex[i] == w)p2 = i;
  102. }
  103. if (-1 != p1&&-1 != p2)//两点均可在图中找到
  104. {
  105. if (G.Edge[p1][p2] == 1)//存在弧
  106. {
  107. return true;
  108. }
  109. return false;
  110. }
  111. return false;
  112. }
  113. bool visited[MaxVerNum];//访问标记数组,用于遍历时的标记
  114. //广度遍历函数 参数:图G,开始结点下标start 作用:宽度遍历
  115. void BFS(Graph G, int start)
  116. {
  117. queue<int> Q;//辅助队列
  118. cout << G.Vex[start];//访问结点
  119. visited[start] = true;
  120. Q.push(start);//入队
  121. while (!Q.empty())//队列非空
  122. {
  123. int v = Q.front();//得到队头元素
  124. Q.pop();//出队
  125. for (int j = 0; j<G.vexnum; j++)//邻接点
  126. {
  127. if (G.Edge[v][j] < INF && !visited[j])//是邻接点且未访问
  128. {
  129. cout << "->";
  130. cout << G.Vex[j];//访问结点
  131. visited[j] = true;
  132. Q.push(j);//入队
  133. }
  134. }
  135. }//while
  136. cout << endl;
  137. }
  138. //深度遍历函数(递归形式)参数:图G,开始结点下标start 作用:深度遍历
  139. void DFS(Graph G, int start)
  140. {
  141. cout << G.Vex[start];//访问
  142. visited[start] = true;
  143. for (int j = 0; j < G.vexnum; j++)
  144. {
  145. if (G.Edge[start][j] <INF && !visited[j])//是邻接点且未访问
  146. {
  147. cout << "->";
  148. DFS(G, j);//递归深度遍历
  149. }
  150. }
  151. }
  152. //最短路径 - Dijkstra算法 参数:图G、源点v3
  153. void Dijkstra(Graph G, int v)
  154. {
  155. //初始化
  156. int n = G.vexnum;//n为图的顶点个数
  157. for (int i = 0; i < n; i++)
  158. {
  159. S[i] = false;
  160. D[i] = G.Edge[v][i];
  161. if (D[i] < INF)Pr[i] = v; //v与i连接,v为前驱
  162. else Pr[i] = -1;
  163. }
  164. S[v] = true;
  165. D[v] = 0;
  166. //初始化结束,求最短路径,并加入S集
  167. for (int i = 1; i < n; i++)
  168. {
  169. int min = INF;
  170. int temp;
  171. for (int w = 0; w < n; w++)
  172. if (!S[w] && D[w] < min) //某点temp未加入s集,且为当前最短路径
  173. {
  174. temp = w;
  175. min = D[w];
  176. }
  177. S[temp] = true;
  178. //更新从源点出发至其余点的最短路径 通过temp
  179. for (int w = 0; w < n; w++)
  180. if (!S[w] && D[temp] + G.Edge[temp][w] < D[w])
  181. {
  182. D[w] = D[temp] + G.Edge[temp][w];
  183. Pr[w] = temp;
  184. }
  185. }
  186. }
  187. //最短路径 - Bellman_Ford算法 参数:图G、源点v 作用:计算不含负圈图的最短路径 返回是否有圈
  188. bool Bellman_Ford(Graph G, int v)
  189. {
  190. //初始化
  191. int n = G.vexnum;//n为图的顶点个数
  192. for (int i = 0; i < n; i++)
  193. {
  194. D[i] = G.Edge[v][i];
  195. if (D[i] < INF)Pr[i] = v; //v与i连接,v为前驱
  196. else Pr[i] = -1;
  197. }
  198. D[v] = 0;
  199. //初始化结束,开始双重循环
  200. for (int i = 2; i<G.vexnum - 1; i++)
  201. for (int j = 0; j<G.vexnum; j++) //j为源点
  202. for (int k = 0; k<G.vexnum; k++) //k为终点
  203. if (D[k] > D[j] + G.Edge[j][k])
  204. {
  205. D[k] = D[j] + G.Edge[j][k];
  206. Pr[k] = j;
  207. }
  208. //判断是否含有负圈
  209. bool flag = true;
  210. for (int j = 0; j<G.vexnum - 1; j++) //j为源点
  211. for (int k = 0; k<G.vexnum - 1; k++) //k为终点
  212. if (D[k] > D[j] + G.Edge[j][k])
  213. {
  214. flag = false;
  215. break;
  216. }
  217. return flag;
  218. }
  219. //最短路径 - Floyd_Wallshall算法 参数:图G 作用:计算不含负圈图的最短路径 返回是否有圈
  220. bool Floyd_Wallshall(Graph G)
  221. {
  222. //初始化
  223. for (int i = 0; i<G.vexnum; i++)
  224. for (int j = 0; j < G.vexnum; j++)
  225. {
  226. if (i == j)F_D[i][j] = 0;
  227. else F_D[i][j] = G.Edge[i][j];
  228. P[i][j] = -1;
  229. }
  230. //初始化结束,开始迭代
  231. for(int k=0;k<G.vexnum;k++)
  232. for (int i = 0; i<G.vexnum; i++)
  233. for (int j = 0; j<G.vexnum; j++)
  234. if (F_D[i][j] > F_D[i][k] + F_D[k][j])
  235. {
  236. F_D[i][j] = F_D[i][k] + F_D[k][j];
  237. P[i][j] = k;
  238. }
  239. bool flag = true;
  240. for (int i = 0; i < G.vexnum; i++)
  241. for (int j = 0; j < G.vexnum; j++)
  242. if (i==j&&F_D[i][j] < 0)
  243. {
  244. flag = false;
  245. break;
  246. }
  247. return flag;
  248. }
  249. //输出最短路径
  250. void Path(Graph G, int v)
  251. {
  252. if (Pr[v] == -1)
  253. return;
  254. Path(G, Pr[v]);
  255. cout << G.Vex[Pr[v]] << "->";
  256. }
  257. // 输出Floyd最短路径 v是终点
  258. void F_Path(Graph G, int v, int w)
  259. {
  260. cout << "->"<< G.Vex[P[v][w]] ;
  261. if (P[v][w] == -1)
  262. return;
  263. F_Path(G, v,P[v][w]);
  264. }
  265. //**********************************************功能实现函数*****************************************//
  266. //打印图的顶点表
  267. void PrintVex(Graph G)
  268. {
  269. for (int i = 0; i < G.vexnum; i++)
  270. {
  271. cout << G.Vex[i] << " ";
  272. }
  273. cout << endl;
  274. }
  275. //打印图的弧矩阵
  276. void PrintEdge(Graph G)
  277. {
  278. for (int i = 0; i < G.vexnum; i++)
  279. {
  280. for (int j = 0; j < G.vexnum; j++)
  281. {
  282. if (G.Edge[i][j] == INF)cout << "∞ ";
  283. else cout << G.Edge[i][j] << " ";
  284. }
  285. cout << endl;
  286. }
  287. }
  288. //创建图功能实现函数 参数:图G InsertNode 作用:创建图
  289. void CreateGraph(Graph &G)
  290. {
  291. VexType v, w;
  292. int vn, an;//顶点数,弧数
  293. cout << "请输入顶点数目:" << endl;
  294. cin >> vn;
  295. cout << "请输入弧数目:" << endl;
  296. cin >> an;
  297. cout << "请输入所有顶点名称:" << endl;
  298. for (int i = 0; i<vn; i++)
  299. {
  300. cin >> v;
  301. if (InsertNode(G, v)) continue;//插入点
  302. else {
  303. cout << "输入错误!" << endl; break;
  304. }
  305. }
  306. cout << "请输入所有弧(每行输入起点,终点及权值):" << endl;
  307. for (int j = 0; j<an; j++)
  308. {
  309. int weight;
  310. cin >> v >> w >> weight;
  311. if (InsertEdge(G, v, w, weight)) continue;//插入弧
  312. else {
  313. cout << "输入错误!" << endl; break;
  314. }
  315. }
  316. cout << "图的顶点及邻接矩阵:" << endl;
  317. PrintVex(G);
  318. PrintEdge(G);
  319. }
  320. //广度遍历功能实现函数 参数:图G 作用:宽度遍历
  321. void BFSTraverse(Graph G)
  322. {
  323. for (int i = 0; i<MaxVerNum; i++)//初始化访问标记数组
  324. {
  325. visited[i] = false;
  326. }
  327. for (int i = 0; i < G.vexnum; i++)//对每个连通分量进行遍历
  328. {
  329. if (!visited[i])BFS(G, i);
  330. }
  331. }
  332. //深度遍历功能实现函数 参数:图G 作用:深度遍历
  333. void DFSTraverse(Graph G)
  334. {
  335. for (int i = 0; i<MaxVerNum; i++)//初始化访问标记数组
  336. {
  337. visited[i] = false;
  338. }
  339. for (int i = 0; i < G.vexnum; i++)//对每个连通分量进行遍历
  340. {
  341. if (!visited[i])
  342. {
  343. DFS(G, i); cout << endl;
  344. }
  345. }
  346. }
  347. //调用最短路径-Dijkstra算法 参数:图G
  348. void Shortest_Dijkstra(Graph &G)
  349. {
  350. char vname;
  351. int v = -1;
  352. cout << "请输入源点名称:" << endl;
  353. cin >> vname;
  354. for (int i = 0; i < G.vexnum; i++)
  355. if (G.Vex[i] == vname)v = i;
  356. if (v == -1)
  357. {
  358. cout << "没有找到输入点!" << endl;
  359. return;
  360. }
  361. Dijkstra(G, v);
  362. cout << "目标点" << "\t" << "最短路径值" << "\t" << "最短路径" << endl;
  363. for (int i = 0; i < G.vexnum; i++)
  364. {
  365. if (i != v)
  366. {
  367. cout << " " << G.Vex[i] << "\t" << " " << D[i] << "\t";
  368. Path(G, i);
  369. cout << G.Vex[i] << endl;
  370. }
  371. }
  372. }
  373. //调用最短路径- - Bellman_Ford算法 参数:图G
  374. void Shortest_Bellman_Ford(Graph &G)
  375. {
  376. char vname;
  377. int v = -1;
  378. cout << "请输入源点名称:" << endl;
  379. cin >> vname;
  380. for (int i = 0; i < G.vexnum; i++)
  381. if (G.Vex[i] == vname)v = i;
  382. if (v == -1)
  383. {
  384. cout << "没有找到输入点!" << endl;
  385. return;
  386. }
  387. if (Bellman_Ford(G, v))
  388. {
  389. cout << "目标点" << "\t" << "最短路径值" << "\t" << "最短路径" << endl;
  390. for (int i = 0; i < G.vexnum; i++)
  391. {
  392. cout << " " << G.Vex[i] << "\t" << " " << D[i] << "\t";
  393. Path(G, i);
  394. cout << G.Vex[i] << endl;
  395. }
  396. }
  397. else
  398. {
  399. cout << "输入的图中含有负圈,不能使用该算法!" << endl;
  400. }
  401. }
  402. //调用最短路径- - Floyd_Wallshall算法 参数:图G
  403. void Shortest_Floyd_Wallshall(Graph &G)
  404. {
  405. if (Floyd_Wallshall(G))
  406. {
  407. cout << "最短路径值" << "\t" << "最短路径" << endl;
  408. for (int i = 0; i < G.vexnum; i++)
  409. for (int j = 0; j < G.vexnum; j++)
  410. {
  411. cout << " "<<F_D[i][j] << " \t";
  412. cout << G.Vex[i];
  413. F_Path(G, i,j);
  414. cout << G.Vex[j] << endl;
  415. }
  416. }
  417. else
  418. {
  419. cout << "输入的图中含有负圈,不能使用该算法!" << endl;
  420. }
  421. }
  422. //菜单
  423. void menu()
  424. {
  425. cout << "************1.创建图 2.广度遍历******************" << endl;
  426. cout << "************3.深度遍历 4.迪杰斯特拉****************" << endl;
  427. cout << "************5.贝尔曼福特 6.弗洛伊德******************" << endl;
  428. cout << "************7.退出*************************************" << endl;
  429. }
  430. //主函数
  431. int main()
  432. {
  433. int choice = 0;
  434. Graph G;
  435. InitGraph(G);
  436. while (1)
  437. {
  438. menu();
  439. printf("请输入菜单序号:\n");
  440. scanf("%d", &choice);
  441. if (7 == choice) break;
  442. switch (choice)
  443. {
  444. case 1:CreateGraph(G); break;
  445. case 2:BFSTraverse(G); break;
  446. case 3:DFSTraverse(G); break;
  447. case 4:Shortest_Dijkstra(G); break;
  448. case 5:Shortest_Bellman_Ford(G); break;
  449. case 6:Shortest_Floyd_Wallshall(G); break;
  450. default:printf("输入错误!!!\n"); break;
  451. }
  452. }
  453. return 0;
  454. }

实验结果

实验结果截图

最短路径算法比较

算法\比较内容适用条件算法思想时间复杂度
Dijkstra无负权的图,单源或多源贪心O(v^2)、O(v^3)
Bellman-Ford可以有负权但无负圈的图动态规划O(v^3)、O(ve)
Floyd-Warshall无负权的图,多源动态规划

O(v^3)

更多数据结构与算法实现:数据结构(严蔚敏版)与算法的实现(含全部代码)

有问题请下方评论,转载请注明出处,并附有原文链接,谢谢!如有侵权,请及时联系。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/在线问答5/article/detail/822022
推荐阅读
相关标签
  

闽ICP备14008679号