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. 好客租房33-事件绑定this指向(总结)

    1推荐使用class的实例方法 //导入react import React from 'react'   import ReactDOM from 'react-dom' //导入组件   // 约 ...

  2. 【Java面试】JVM如何判断一个对象可以被回收

    Hi, 我是Mic. 今天分享一道一线互联网公司必问的面试题. "JVM如何判断一个对象可以被回收" 关于这个问题,来看看普通人和高手的回答. 普通人: 嗯.......... 高 ...

  3. 2021年第十二届蓝桥杯javaA组省赛部分题目

    试题 D: 路径 本题总分:10 分 [问题描述] 小蓝学习了最短路径之后特别高兴,他定义了一个特别的图,希望找到图 中的最短路径. 小蓝的图由 2021 个结点组成,依次编号 1 至 2021. 对 ...

  4. select into 与 insert into 的区别

    1.select * into table_A  from table_B table_A是个新创建表,table_B是个已经存在的表. 2.insert into table_A from tabl ...

  5. Python的关键字参数与斜杠“/”

    Python3.8 新增了一种语法,可以使用斜杠 / 占据一个参数的位置,表示在此之前的参数都只接受位置参数的传参形式. 例如,对以下函数声明: def func(a, b, /, c, d, *, ...

  6. .NET C#杂谈(1):变体 - 协变、逆变与不变

    0. 文章目的:   介绍变体的概念,并介绍其对C#的意义 1. 阅读基础   了解C#进阶语言功能的使用(尤其是泛型.委托.接口) 2. 从示例入手,理解变体   变体这一概念用于描述存在继承关系的 ...

  7. 表达式的动态解析和计算,Flee用起来真香

    前言 在很多项目中经常会出现需要动态解析表达式和计算的场景,比如一些自动审核规则,或者是一些变量的值通过维护的公式在运行过程中动态算出:由于场景需求,都需要比较灵活的配置对应的表达式,然后希望在需要的 ...

  8. BUUCTF-神秘龙卷风

    神秘龙卷风 通过提示知道压缩包密码是四位纯数字,通过爆破得到 得到一串编码 看样子应该是brainfuck编码 flag{e4bbef8bdf9743f8bf5b727a9f6332a8}

  9. 4种方法教你如何查看java对象所占内存大小

    摘要:本文讲述4种查看java对象所占内存大小的方法 本文分享自华为云社区<查看java对象所占内存大小>,作者:xiewenci. 计算java对象所占内存大小 1.使用jdk8自带AP ...

  10. Python教程:随机验证码生成和join 字符串

    函数:string.join() Python中有join()和os.path.join()两个函数,具体作用如下: join(): 连接字符串数组.将字符串.元组.列表中的元素以指定的字符(分隔符) ...