Floyd算法:

  Floyd算法用来找出每对顶点之间的最短距离,它对图的要求是,既可以是无向图也可以是有向图,边权可以为负,但是不能存在负环(可根据最小环的正负来判定).

基本算法:

  Floyd算法基于动态规划的思想,以 u 到 v 的最短路径至少经过前 k 个点为转移状态进行计算,通过 k 的增加达到寻找最短路径的目的.当 k 增加 1 时,最短路径要么不边,如果改变,必经过第 k 各点,也就是说当起点 u 到第 k 个点的最短距离加上第 k 个点到终点 v 的最短路径小于不经过第 k 个节点的最优最短路经长度的时候更新 u 到 v 的最短距离. 当 k = n 时, u 到 v 的最短路径就确定了.

伪代码:

  图的存储用邻接矩阵 gra[][] 来记录,如果 u 与 v 之间没有边直接相连,则 gra[u][v] = INF; dist[][] 记录最终的最短路. pre[i][j] 存储 i 到 j 路径中 i 的后一个节点.

  1): 初始化:将 gra 中的数据复制到 dist 中作为每对顶点间的最短路的初值, pre[i][j] = j;

  2): k 从 1 到 n 循环 n 次, 每次循环中枚举图中不同的两点 u, v, 如果 dist[u][v] > dist[u][k] + dist[k][v], 则更新 dist[u][v] = dist[u][k] + dist[k][v], 更新 pre[u][v] = pre[u][k].

  3): 最后 dist[u][v] 数组中存储的就是 u 到 v 的最短距离, u 到 v 的路径, 则可以按照顺序查找就好了.

以图为例:

有一个如下的无向图, “D”数组存储最短路值, “P” 数组存储最短路径:

假设现在每对顶点之间的路径只允许经过点 “1” , 则更新后的每对顶点之间的距离:

这里看到点 “2” 到点 “3” 的距离经过点 “1” 得到了更新,同时更新了用于记录路径的 P 数组.

第二步,允许每对顶点之间的最短路径经过点 “1” 和点 “2”,则更新后的数组为:

可以看到得到更新的路径为:

1 ---> 4, 经过点 “2” 得到更新

1 ---> 5, 经过点 “2” 得到更新

3 ---> 5. 经过点 “1 --- > 2” 得到更新

第三步: 允许经过点 “1”, “2” 和点 “3” 则更新后的数组为:

这则说明,上一步的最短路径不需要更新.

第四步, 允许经过点 “1”, “2” , “3” 和点 “4” 则更新后的数组为:

可以看到 3 ---> 5 的路径经过点 “4” 得到了更新(原先是 3 ---> 1 ---> 2 ---> 5, w = 9)

第五步, 允许任意两点之间的最短路径可以经过全部点,则更新后的数组为:

这次得到更新的路径为:

1 ---> 4 的路径. 更新为 “1 ---> 2 ---> 5 ---> 4, w = 5” (原路径为 1 ---> 2 ---> 4, w = 7)

2 ---> 3 的路径. 更新为 “2 ---> 5 ---> 4 ---> 3, w = 7” (原路经为 2 ---> 1 ---> 3, w = 8)

2 ---> 4 的路径. 更新为 “2 --> 5 --> 4, w = 2” (原路径为 2 ---> 4, w = 4)

无向图反之亦然.

至此最短路径就寻找完毕. dist[i][j] 数组里面保存的就是 i 到 j 的最短距离.如果要查寻路径, 则按照查数组 pre 就好.比如查询 “2” 到 “3” 的路径:

则寻找     pre[2][3] = 5,  2 ---> 5

继续寻找  pre[5][3] = 4,  2 ---> 5 ---> 4

继续寻找  pre[4][3] = 3, 2 ---> 5 ---> 4 ---> 3

由于此时 i = j = 3, 则 “2” 到 “3” 的最短路径已找到为: 2 ---> 5 ---> 4 ---> 3

  1. #include <bits/stdc++.h>
  2.  
  3. typedef long long LL;
  4. const int MAXN = ;
  5. const int INF = 0x3f3f3f3f;
  6. using namespace std;
  7.  
  8. int pre[MAXN + ][MAXN + ], dist[MAXN + ][MAXN + ]; //pre 储存路径; dist 存储最短距离
  9. void floyd(int n, int gra[][MAXN + ]) {
  10. for(int i = ; i <= n; i++) for(int j = ; j <= n; j++) dist[i][j] = gra[i][j], pre[i][j] = j; //初始化
  11. for(int k = ; k <= n; k++) { //尝试经过 k 个点对每对顶点之间的距离进行更新
  12. for(int i = ; i <= n; i++) {
  13. for(int j = ; j <= n; j++) {
  14. if(dist[i][k] != INF && dist[k][j] != INF && dist[i][k] + dist[k][j] < dist[i][j]) {
  15. dist[i][j] = dist[i][k] + dist[k][j];
  16. pre[i][j] = pre[i][k];
  17. }
  18. }
  19. }
  20. }
  21. }
  22.  
  23. int pfpath(int u, int v) { //打印最短路径
  24. while(u != v) {
  25. cout << u << " ";
  26. u = pre[u][v];
  27. }
  28. cout << u << endl;
  29. }
  30.  
  31. int gra[MAXN + ][MAXN + ];
  32. int main() {
  33. int n, m;
  34. while(cin >> n >> m){ // n 个点, m 条边
  35. for(int i = ; i <= n; i++) for(int j = -; j <= n; j++){
  36. gra[i][j] = (i == j ? : INF);
  37. }
  38. for(int i = ; i < m; i++) {
  39. int u, v, w; cin >> u >> v >> w;
  40. gra[u][v] = gra[v][u] = w; //无向图
  41. }
  42. floyd(n, gra);
  43. }
  44. return ;
  45. }

Floyd 算法求多源最短路径的更多相关文章

  1. 51nod 1445 变色DNA ( Bellman-Ford算法求单源最短路径)

    1445 变色DNA 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 有一只特别的狼,它在每个夜晚会进行变色,研究发现它可以变成N种颜色之一,将这些颜色标号为0,1 ...

  2. Dijkstra算法求单源最短路径

    Description 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店 ...

  3. Floyd算法解决多源最短路径问题

    Floyd-Warshall算法是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权(但不可存在负权回路)的最短路径问题,同时也被用于计算有向图的传递闭包. Floyd-Warshall算法 ...

  4. SPFA算法与dijkstra算法求单源最短路径的比较

    SPFA是运用队列,把所有的点遍历到没有能更新的,点可以重复入队 如题http://www.cnblogs.com/Annetree/p/5682306.html dijkstra是每次找出离源点最近 ...

  5. AOJ GRL_1_A: Single Source Shortest Path (Dijktra算法求单源最短路径,邻接表)

    题目链接:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_1_A Single Source Shortest Path In ...

  6. [Python] 弗洛伊德(Floyd)算法求图的直径并记录路径

    相关概念 对于一个图G=(V, E),求图中两点u, v间最短路径长度,称为图的最短路径问题.最短路径中最长的称为图的直径. 其中,求图中确定的某两点的最短路径算法,称为单源最短路径算法.求图中任意两 ...

  7. _DataStructure_C_Impl:Floyd算法求有向网N的各顶点v和w之间的最短路径

    #include<stdio.h> #include<stdlib.h> #include<string.h> typedef char VertexType[4] ...

  8. Dijkstra算法详细(单源最短路径算法)

    介绍 对于dijkstra算法,很多人可能感觉熟悉而又陌生,可能大部分人比较了解bfs和dfs,而对dijkstra和floyd算法可能知道大概是图论中的某个算法,但是可能不清楚其中的作用和原理,又或 ...

  9. 【转】Dijkstra算法(单源最短路径)

    原文:http://www.cnblogs.com/dolphin0520/archive/2011/08/26/2155202.html 单源最短路径问题,即在图中求出给定顶点到其它任一顶点的最短路 ...

随机推荐

  1. Java进阶(三)Java安全通信:HTTPS与SSL

    通过一个系统,接触到了Java安全机制,故作一小节,供朋友们参考学习. 1. HTTPS概念 1)简介 HTTPS(全称:Hypertext Transfer Protocol over Secure ...

  2. UNIX环境高级编程——死锁

    操作系统中有若干进程并发执行,它们不断申请.使用.释放系统资源,虽然系统的进程协调.通信机制会对它们进行控制,但也可能出现若干进程都相互等待对方释放资源才能继续运行,否则就阻塞的情况.此时,若不借助外 ...

  3. 【Unity Shaders】Using Textures for Effects——通过修改UV坐标来滚动textures

    本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...

  4. Leetcode_80_Remove Duplicates from Sorted Array II

    本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/43835055 Follow up for "Re ...

  5. Java学习笔记(二)事件监听器

    Java实现对组件事件(如单击.输入等)的监听和JavaScript类似,都是先添加Listener,再写触发函数,不同的是,Java实现监听前必须使用implements将各个接口添加到类内. 相关 ...

  6. (视频)《快速创建网站》2.1 在Azure上创建网站及网站运行机制

    现在让我们开始一天的建站之旅. 本文是<快速创建网站>系列的第2篇,如果你还没有看过之前的内容,建议你点击以下目录中的章节先阅读其他内容再回到本文. 1. 网站管理平台WordPress和 ...

  7. UML之概述

              UML,英文名曰:Unified  Modeling Language,她还有个中文名字叫统一建模语言,简单的来说,她就是一种绘制软件蓝图的标准语言.她的表达能力特别强,可以描述开 ...

  8. zTree的调用设使用(跨两个系统,两类技术实现的项目案例SpringMVC+Spring+MyBatis和Struts2+Spring+ibatis框架组合)

    1.从zTree官网上下载zTree的包,zTree的官方网址是:http://www.ztree.me/v3/main.php#_zTreeInfo 2.引入zTree所需的依赖,例如(jQuery ...

  9. linux下用gtk+写比赛赌博GUI小游戏

    游戏界面全部由gtk的GUI完成,没有使用openGL之类的高端货. 游戏玩法就是8位选手比赛跑步,你可以在赛前赌哪位选手会赢,如果输了cash会被扣除,反之cash会增加. 无聊写了3个选项:小数时 ...

  10. 【Android 应用开发】BluetoothServerSocket详解

    一. BluetoorhServerSocket简介 1. 继承关系 public final class BluetoothServerSocket extends Object implement ...