Floyd算法的原理,状态表示及优化
首先,Floyd算法是基于动态规划的思想, f[k][i][j]表示的是从节点i走到节点j,中间经过的节点(节点i和节点j分别是起点和终点,属于已经确定的点,不被记入中间点)是1~k中的节点的所有路径的集合,集合的属性是最小值.
状态转移:
我们把集合不重不漏的分为两部分:
1.中间经过的点包含第k个点.
状态表示:f[k-1][i][j]
2.中间经过的点不包含第k个点. (
状态表示: f[k-1][i][k]+f[k-1][k][j])
因此状态转移方程为:
f[k][i][j]=min(f[k-1][i][j],f[k-1][i][k]+f[k-1][k][j])
利用滚动数组进行优化得:
f[i][j]=min(f[i][j],f[i][k]+f[k][j])
Floyd算法保存路径:
利用path[i][j]保存从i走到j的最短路径中中间第一个经过的点(正向输出路径),或者path[i][j]保存从i走到j的最短路径中中间经过的点中的最后一个经过的点(反向输出路径).
状态转移方程:
if(f[i][j]>f[i][k]+f[k][j])
path[i][j]=path[i][k]
注:这里的中间经过的点是不包括起点i和终点j的.
Floyd算法变形:
poj3615-Cow Hurdles
poj2253-Frogger
关于Floyd算法变形的一些心得:
我们要从状态转移方程入手,在状态转移方程的过程中维护一些额外信息,或者是状态转移方程的状态表示稍微改变一下,状态转移方程做出相对应的改变.
另外Floyd算法还可以进行传递点与点之间的关系!!!