所有节点对的最短路径之Floyd-Warshall

来源:互联网 发布:怎么用vs2013写c语言 编辑:程序博客网 时间:2024/04/28 20:42

Floyd-Warshall的适用范围

1、求所有节点对的最短路径

2、边的权重可以为负

3、不能存在负环路

Floyd-Warshall算法的描述

Floyd-Warshall实际上是一种动态规划的思想。假如图中有n个节点,编号为1~n,我们令d[k][i][j]表示只能使用1~k号节点作为中间节点时,节点i到j的最短路径距离。d[0][i][j]表示没有中间节点时,i到j的最短路径距离,d[1][i][j]表示只能有节点1作为中间节点时,i到j的最短路径长度。d[k][i][j]可以分为两种情况:

1、节点k在i到j的最短路径上,此时d[k][i][j]=d[k-1][i][k]+d[k-1][k][j]

2、节点k不在i到j的最短路径上,此时d[k][i][j]=d[k-1][i][j]

所以d[k][i][j]=min{d[k-1][i][j],d[k-1][i][k]+d[k-1][k][j]}

floyd的java模板

int n;//节点的总个数int d[][][];//d[k][i][j]:能使用1~k号节点作为中间节点时,节点i到j的最短路径距离int w[][];//w[i][j]:边(i,j)的权重,若i,j之间没有边,则令w[i][j]=MAX,若i==j,则w[i][j]=0int MAX=0xfffff;//很大的一个数,用来表示两个节点之间没有边void floyd(){for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){d[0][i][j]=w[i][j];}}for(int k=1;k<=n;k++){for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){if(i==j) continue;d[k][i][j]=Math.min(d[k-1][i][j], d[k-1][i][k]+d[k-1][k][j]);}}}}


通过观察动态转移方程d[k][i][j]=min{d[k-1][i][j],d[k-1][i][k]+d[k-1][k][j]},我们可以发现k阶段的状态(d[k][i][j]),只与k-1阶段的转态(d[k-1]..)的状态有关,我们可以将上面的代码简化成

floyd简化版java模板

int n;//节点的总个数int d[][];//d[i][j]:表示当前求得的i到j的最短路径距离int w[][];//w[i][j]:边(i,j)的权重,若i,j之间没有边,则令w[i][j]=MAX,若i==j,则w[i][j]=0int MAX=0xfffff;//很大的一个数,用来表示两个节点之间没有边void floyd(){for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){d[i][j]=w[i][j];}}for(int k=1;k<=n;k++){for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){if(i==j) continue;if(d[i][j]>d[i][k]+d[k][j]){d[i][j]=d[i][k]+d[k][j];}}}}}



0 0
原创粉丝点击