Floyd-Warshall算法求任意两点间的最短路(图论算法)
2017-01-11 14:43
260 查看
算法思路简介
假设只使用顶点0~k和 i,j ,并且我们记顶点i到j的最短路径长为dp[ k + 1 ][ i ][ j ],k = -1表示只使用i,j,所以dp[ 0 ][ i ][ j ] = cost[ i ][ j ].只使用0~k时,有经过k和不经过k两种情况,所以dp[ k + 1 ][ i ][ j ] = min( dp[ k ][ i ][ j ] , dp[ k ][ i ][ k ] + dp[ k ][ k ][ j ] )
上面的cost数组表示边的权重
dp数组的初始值是边的权重(如果存在边)
当顶点i 和 j 之间的路径不存在时,dp[ k ][ i ][ j ] = INF
这便变成了一个典型的dp,所以这个三维数组就可以直接用一个二维的代替: dp[ i ][ j ] = min( dp[ i ][ j ], dp[ i ][ k ] + dp[ k ][ j ] )
实现:
int d[MAX_V][MAX_V]; int V; void warshall_floyd() { for(int k = 0; k < V; k++) for(int i = 0; i < V; i++) for(int j = 0; j < V; j++) d[i][j] = min( d[i][j], d[i][k]+d[k][j] ); }
代码解析
为什么最外层循环是k是为了更新dp[ i ][ j ]
假设把k的循环放在最内层
那么dp[ i ][ j ]就只会更新 “ 一次 ”,打个比方:
i = 1,j = 2时,dp[ i ][ j ]会被连续更新k次,然而此时还有很多地方都没有被计算,比如k = 10时,
dp[ 1 ][ 2 ] = min( dp[ 1 ][ 2 ], dp[ 1 ][ 10] + dp[ 10 ][ 2 ] )
看起来没啥问题,但是呢,这时 dp[ 1 ][ 10] 和 dp[ 10 ][ 2 ]的结果都还不知道,而当计算出dp[ 1 ][ 10] 和 dp[ 10 ][ 2 ]后,dp[ 1 ][ 2 ]却不再被更新,导致无法得到正确结果
时间复杂度
不用多说肯定是 O( V^3 )
相关文章推荐
- Floyd-Warshall算法(求解任意两点间的最短路) 详解 + 变形 之 poj 2253 Frogger
- 任意两点最短路 Floyd-Warshall算法 传递闭包
- POJ 2139 Six Degrees of Cowvin Bacon(任意两点最短路,Floyd)
- 基础Floyd--任意两点间最短路
- Cow Contest(POJ 3660)(Floyd)(任意两点间最短路)
- Floyd-Warshall算法--求任意两点最短距离
- 任意两点间的最短路径---floyd_warshall算法
- floyd 任意两点最短路
- 任意两点的最短路问题 Floyd-Warshall算法
- acm_floyd任意两点的最短路(最简单无脑的最短路算法)
- 【算法】Floyd-Warshall算法(任意两点间的最短路问题)(判断负圈)
- AOJ GRL_1_C: All Pairs Shortest Path (Floyd-Warshall算法求任意两点间的最短路径)(Bellman-Ford算法判断负圈)
- ACM模板 图论,Floyd 任意两点间最短路
- Floyd-Warshall算法求任意两点间最短路径
- POJ - 2139 Six Degrees of Cowvin Bacon(任意两点最短路,Floyd)
- 任意两点之间的最短路径问题(Floyd-Warshall算法)
- Floyd-Warshall算法 (任意两点间的最短路问题)
- P103 任意两点之间的最短路问题 Floyd_warshall算法
- 任意两点间的最短路问题(Floyd-Warshall算法)
- POJ 1125 Stockbroker Grapevine(任意两点的最短路,FLoyed 算法)