图算法之Floyd-Warshall 算法-- 任意两点间最小距离
1.Floyd-Warshall 算法
给定一张图,在o(n3)时间内求出任意两点间的最小距离,并可以在求解过程中保存路径
2.Floyd-Warshall 算法概念
这是一个动态规划的算法。
将顶点编号,假设依次为0,1,2…n-1,现在假设DP[i][j][k]表示从i出发,结束于j的满足经过结点的编号至多为k的最短路径,由此性质易知,在易知DP[i][j][k]时,若要求DP[i][j][k+1],有两种情况要考虑:
- DP[i][j][k+1]所表征的路径经过结点k+1,此时DP[i][j][k+1] = DP[i][k+1][k] + DP[k+1][j][k]
- DP[i][j][k+1]所表征的路径不经过结点k+1,此时DP[i][j][k+1] = DP[i][j][k],不用更新表项
属于哪种情况只需进行一次比较选择较小的即可,当第n-1轮循环结束,表项中的值DP[i][j]就代表了顶点i , j之间的最短距离,由算法的描述易知,时间复杂度必然是O(N3),但是空间复杂度可以通过复用DP数组减少到O(N2),这是为什么呢?如何保存路径?
分析1:要证明DP数组只需两维,只需证明第k+1轮循环中DP数组前面被改动的部分不会被用到即可且用到的一定没有被改动即可。假设第i论循环中dp[i][j]及之前的dp数组项已经被计算出来,接下来的运算中dp[inext][jnext],需要计算上面两种情况下的值:
- 对于第1种情况,DP[inext][jnext][k+1] = DP[inext][k+1][k] + DP[k+1][jnext][k],对于DP[inext][k+1][k],如果它在本轮循环被更新,那么它实际上可以被标识为DP[inext][k+1][k+1],这就是一个矛盾,第k+1个点已经作为端点存在,却又说k+1个顶点可能在路径中存在。所以它不可能在本轮被更新,即实际上它还是DP[inext][k+1][k],DP[k+1][jnext][k]的分析相同,见下面的分析2.
- 对第2种情况,DP[inext][jnext][k+1] = DP[inext][jnext][k] , 要么inext>i,要么inext==i&&jnext>j,即DP[inext][jnext]之前肯定未被更新,不存在问题。
分析2:一个令人迷惑的问题就是在第k+1轮循环计算DP[i][k+1](DP[k+1][j]的分析相同),按照上面两种情况分类 ,二者相等, 可以知道的确是不用更新的
- 对第一种情况:DP[i][k+1][k+1] = DP[i][k+1][k] + DP[k+1][k+1][k] = DP[i][k+1][k]
- 对第二种情况:DP[i][k+1][k+1] = DP[i][k+1][k]
分析3:初始状况的分析,初始状况相当于不经过任何结点,对于任意两个顶点 i , j ,自然有
- 若 i , j 之间有边相连,则 DP[i][j] = cost(i,j)
- 反之 ,DP[i][j] = INF
分析4 : 如何记录路径,设path[i][j]表示 i 到 j 的最短路径中 i 的后继顶点,初始情况下,若i ,j 之间有边相连,path[i][j] = j ,否则,path[i][j] = –1,在不断收敛的过程中,若当前最短路径有变化,path[i][j] = path[i][k+1]
3.代码
头文件:
/* |
实现文件:
/* |
测试文件:
/* |
测试用例:
1000 表示无穷大
0 1 4 1000 1000 1000 |
算法结果:

图算法之Floyd-Warshall 算法-- 任意两点间最小距离的更多相关文章
- AOJ GRL_1_C: All Pairs Shortest Path (Floyd-Warshall算法求任意两点间的最短路径)(Bellman-Ford算法判断负圈)
题目链接:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_1_C All Pairs Shortest Path Input ...
- 【算法】Floyd-Warshall算法(任意两点间的最短路问题)(判断负圈)
求解所有两点间的最短路问题叫做任意两点间的最短路问题. 可以用动态规划来解决, d[k][i][j] 表示只用前k个顶点和顶点i到顶点j的最短路径长度. 分两种情况讨论: 1.经过顶点k, d[k] ...
- 任意两点间的最短路问题(Floyd-Warshall算法)
/* 任意两点间的最短路问题(Floyd-Warshall算法) */ import java.util.Scanner; public class Main { //图的顶点数,总边数 static ...
- Floyd—Warshall算法
我们用DP来求解任意两点间的最短路问题 首先定义状态:d[k][i][k]表示使用顶点1~k,i,j的情况下,i到j的最短路径 (d[0][i][j]表示只使用i和j,因此d[0][i][j] = c ...
- LCA - 求任意两点间的距离
There are n houses in the village and some bidirectional roads connecting them. Every day peole alwa ...
- 任意两点间最短距离floyd-warshall ---- POJ 2139 Six Degrees of Cowvin Bacon
floyd-warshall算法 通过dp思想 求任意两点之间最短距离 重复利用数组实现方式dist[i][j] i - j的最短距离 for(int k = 1; k <= N; k++) f ...
- Floyed-Warshall算法(求任意两点间最短距离)
思路:感觉有点像暴力啊,反正我是觉得很暴力,比如求d[i][j],用这个方法求的话,就直接考虑会不会经过点k(k是任意一点) ,最终求得最小值 看代码 #include<iostream> ...
- Dijkstra算法:任意两点间的最短路问题 路径还原
#define _CRT_SECURE_NO_WARNINGS /* 7 10 0 1 5 0 2 2 1 2 4 1 3 2 2 3 6 2 4 10 3 5 1 4 5 3 4 6 5 5 6 9 ...
- 任意两点间的最短路问题(Floyd-Warshall算法)
#define _CRT_SECURE_NO_WARNINGS /* 7 10 0 1 5 0 2 2 1 2 4 1 3 2 2 3 6 2 4 10 3 5 1 4 5 3 4 6 5 5 6 9 ...
随机推荐
- 【Tech】YCSB-0.1.3安装使用
1. 下载YCSB 0.1.3: wget https://github.com/brianfrankcooper/YCSB/archive/0.1.3.tar.gz 如果提示“wget:命令没找到” ...
- iPhone 如何设置彩信 ?
使用 iPhone 时,不能使用短信发送图片,肿么办 ? 当然,它会提示你,要你设置彩信.关键是,该怎么设置彩信呢 ? · 首先,打开 “设置” - “蜂窝移动网络” - “蜂窝移动数据网络” (1) ...
- MySQL 跳过同步错误方法
最近MySQL 遇到了同步问题,现整理一下常遇到的错误的解决方法,备用. 方法一:手动设置动态参数 sql_slave_skip_counter 我常用的脚本: stop slave sql_thre ...
- PhpStorm+PhpStudy+xdebug 配置图解
1.配置niginx.ini,新增 server节点,比如使用9200 端口 server { listen 9200;#本地调试,不用80端口 server_name localhost; #cha ...
- hiho #1332 : 简单计算器 栈+递归
#1332 : 简单计算器 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 编写一个程序可以完成基本的带括号的四则运算.其中除法(/)是整除,并且在负数除法时向0取整.( ...
- git(icode)分支及发布管理方式
如果git(icode)不加管理,可能出现枝节蔓生.四处开放的版本库.到处都是分支,完全看不出主干发展的脉络,造成下图的局面: 为了降低合并和版本管理的成本,团队引入一种值得借鉴的管理方式(link) ...
- open_binary_frm
参数uchar* head 是已经分配好内存的64个字节的地址 http://mysql.taobao.org/monthly/2015/08/07/ /** *先从.frm文件读取64字节 *第28 ...
- git subtree有效管理公共第三方lib
如果你的项目中有很多第三方的lib,你希望使用它,并且也希望可能对该lib做修改并且贡献到原始的项目中去,或者你的项目希望模块化,分为几个repo单独维护,那么git subtree就是一个选择.gi ...
- 51nod1295 XOR key
第一次写可持久化trie指针版我... //Null 的正确姿势终于学会啦qaq... #include<cstdio> #include<cstring> #include& ...
- DOM应用
父级.removeChild(子节点);父级.appendChild(子节点);父级.insertBefore(子节点, 在谁之前); 创建元素: <script> window.onlo ...