Floyd本质上使用了DP思想,我们定义\(d[k][x][y]\)为允许经过前k个节点时,节点x与节点y之间的最短路径长度,显然初始值应该为\(d[k][x][y] = +\infin (k, x, y\in[1, n])\);对于有边直接连接的两点\(x\)和\(y\),\(d[k][x][y] = 边长\)。

转移方程:\(f[k][x][y] = min\{f[k - 1][x][y], f[k - 1][x][k] + f[k - 1][k][y]\}\)

考虑状态压缩,显然\(f[k][x][k]\)是一定等于\(f[k - 1][x][k]\),因为\(x\)到\(k\)的路径不可能以点\(k\)本身为中转节点;同理,\(f[k][k][y] = f[k - 1][k][y]\)。

于是,我们可以直接压缩掉第一维(\(k\)),新的状态为\(d[x][y]\)(\(x\)和\(y\)两点的最短路径长度),转移方程为\(f[x][y] = min\{f[x][y], f[x][k] + f[k][y]\}\)

代码实现:

for(int k = 1; k <= n; k++) {
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
}
}
}

Floyd的思想其实就是“通过逐步引入新的中继节点,来计算对应节点/状态间的最优路径”。在标准的Floyd算法中,“最优路径”指的就是最短路,但实际上,Floyd算法还可以解决一些其他的问题.

比如这道题(洛谷P2888),我们根据Floyd的基本思想,就可以设计出转移方程\(f[x][y] = min\{f[x][y], max\{f[x][k] + f[k][y]\}\}\)

具体实现(其实就只改了转移方程):

for(int k = 1; k <= n; k++) {
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
d[i][j] = min(d[i][j], max(d[i][k], d[k][j]));
}
}
}

Updated on 2022/8/7

关于Floyd思想的另一种应用

其实Floyd还可以处理支持传递闭包的问题。

集体实现:

for(int k = 1; k <= n; k++) {
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
d[i][j] |= d[i][k] & d[k][j];
// 只要d[i][k]和d[k][j]都能满足,那么d[i][j]也能满足
}
}
}

直接上例子:CF500B New Year Permutation

这道题中,数组中「元素的交换」就支持传递闭包,即:若a和b可以交换,b和c也可以交换,那么a和c就一定可以通过b来间接交换。所以,我们也可以使用Floyd算法来解决。

Floyd算法详解的更多相关文章

  1. 【最短路径Floyd算法详解推导过程】看完这篇,你还能不懂Floyd算法?还不会?

    简介 Floyd-Warshall算法(Floyd-Warshall algorithm),是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法,与Dijkstra算法类似.该算法名称以 ...

  2. Floyd 算法详解

    Floyd-Warshall Floyd算法,是一种著名的多源最短路算法. 核心思想: 用邻接矩阵存储图,核心代码为三重循环,第一层枚举中间点k,二三层分别枚举起始点i与目标点j.然后判断经过中间点k ...

  3. 最短路径Dijkstar算法和Floyd算法详解(c语言版)

    博客转载自:https://blog.csdn.net/crescent__moon/article/details/16986765 先说说Dijkstra吧,这种算法只能求单源最短路径,那么什么是 ...

  4. BM算法  Boyer-Moore高质量实现代码详解与算法详解

    Boyer-Moore高质量实现代码详解与算法详解 鉴于我见到对算法本身分析非常透彻的文章以及实现的非常精巧的文章,所以就转载了,本文的贡献在于将两者结合起来,方便大家了解代码实现! 算法详解转自:h ...

  5. kmp算法详解

    转自:http://blog.csdn.net/ddupd/article/details/19899263 KMP算法详解 KMP算法简介: KMP算法是一种高效的字符串匹配算法,关于字符串匹配最简 ...

  6. 机器学习经典算法详解及Python实现--基于SMO的SVM分类器

    原文:http://blog.csdn.net/suipingsp/article/details/41645779 支持向量机基本上是最好的有监督学习算法,因其英文名为support vector  ...

  7. [转] KMP算法详解

    转载自:http://www.matrix67.com/blog/archives/115 KMP算法详解 如果机房马上要关门了,或者你急着要和MM约会,请直接跳到第六个自然段.    我们这里说的K ...

  8. 【转】AC算法详解

    原文转自:http://blog.csdn.net/joylnwang/article/details/6793192 AC算法是Alfred V.Aho(<编译原理>(龙书)的作者),和 ...

  9. KMP算法详解(转自中学生OI写的。。ORZ!)

    KMP算法详解 如果机房马上要关门了,或者你急着要和MM约会,请直接跳到第六个自然段. 我们这里说的KMP不是拿来放电影的(虽然我很喜欢这个软件),而是一种算法.KMP算法是拿来处理字符串匹配的.换句 ...

随机推荐

  1. mysql外键与表查询

    目录 自增特性 外键 外键关系 外键创建 外键的约束效果 级联更新级联删除 多对多关系 一对一关系 表查询关键字 select与from where筛选 group by分组 练习 关系练习 查询练习 ...

  2. PostgreSQL(一) 编译安装运行

    原创,如转发需注明出处. 多年没写博客,一直用的个人笔记软件,最近准备阅读PostgreSQL源码,故记录.(这两年PostgreSQL数据库在某些环境下是比较火的,原因想必大家都清楚.) Postg ...

  3. 【Java面试】说说你对Spring MVC的理解

    一个工作了7年的粉丝,他说在面试之前,Spring这块的内容准备得很充分. 而且各种面试题也刷了,结果在面试的时候,面试官问:"说说你对Spring MVC的理解". 这个问题一下 ...

  4. mybatis 转义符号

    < <= > >= & ' " < <= > >= & &apos; "

  5. 遍历list集合泛型为map

    public class ListAddMap { public static void main( String args[] ) { List<Map<String, Object&g ...

  6. Kubernetes client-go Informer 源码分析

    概述ControllerController 的初始化Controller 的启动processLoopHandleDeltas()SharedIndexInformersharedIndexerIn ...

  7. 更换conda镜像源、pip镜像源

    镜像源一般有两点特别需要注意,一个是Conda源,一个是Pip源: 更换Conda源,以更换清华Conda源为例: Anaconda 镜像使用帮助 Anaconda 是一个用于科学计算的 Python ...

  8. VTK 在WINDOWS上的安装使用

    参考:http://www.vtk.org/Wiki/VTK/Building/Windows#Step_5_-_Open_the_Visual_Studio_project

  9. LVS简单搭建(一)

    先说一个坑: 192.168.65.110为虚拟ip,在主节点设置(ifconfig  eth0:8 192.168.65.110/24),其他子节点要与主节点保持一致(ifconfig  lo:3  ...

  10. 循序渐进 Redis 分布式锁(以及何时不用它)

    场景 假设我们有个批处理服务,实现逻辑大致是这样的: 用户在管理后台向批处理服务投递任务: 批处理服务将该任务写入数据库,立即返回: 批处理服务有启动单独线程定时从数据库获取一批未处理(或处理失败)的 ...