floyd可以在O(n3)的时间复杂度,O(n2)的空间复杂度下求解正权图中任意两点间的最短路长度.

本质是动态规划.

定义f[k][i][j]表示从i出发,途中只允许经过编号小于等于k的点时的最短路.(i,j可以大于k但i到j的路径上的其他点必须编号小于等于k).

转移时从第k层的DP数组f[k][][]求解第k+1层的DP数组f[k+1][i][j].

不妨将f[k+1][][]全部初始化为inf(一个足够大的值,可以是1000000,0x3f3f3f3f,或者其他的东西).

一条路径如果保证中转的点编号小于等于k,那么一定也满足经过的点的编号小于等于k+1.于是可以先将上一层的dp数组直接复制到第k+1层,f[k+1][i][j]=f[k][i][j].

接下来考虑经过了第k+1个点作为中转点的最短路.我们枚举(i,j),i!=k+1,j!=k+1,然后令f[k+1][i][j]=min(f[k+1][i][j],f[k][i][k+1]+f[k][k+1][j]).

直接这么写的空间复杂度是O(n3),接下来我们把空间压到O(n2).i,j这两维都是压不掉的,所以我们把k这一维压掉.

f[i][j]现在存的是f[k][i][j].接下来我们把f[i][j]进行更新使得它里面的数值变为f[k+1][i][j].

注意正权图的最短路中显然没有环,那么f[k][k+1][i]和f[k][k][i]的数值是相等的,f[k][i][k+1]和f[k+1][i][k+1]的数值也是相等的.(起点/终点当中有一个点是k+1,那么在中转点中允许经过k+1不会让这个最短路变短).也就是说,从f[k][][]转移到f[k+1][][]的时候,第k+1行和第k+1列都是不需要更新的.

而f[k+1][i][j]=min(f[k+1][i][j],f[k][i][k+1]+f[k][k+1][j]).用到的正是f[k][][]的第k+1行和第k+1列.

那么我们只需用f[i][j]的第k+1行第k+1列去更新其他行列的位置,就完成了f[k][i][j]到f[k+1][i][j]的转移.

于是我们得到了floyd算法的经典实现:

for(int k=1;k<=n;++k)//n为图的点数
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
f[i][j]=min(f[i][j],f[i][k]+f[k][j])

另一种实现:

for(int k=0;k<n;++k)
for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
if(i!=k&&j!=k&&i!=j)f[i][j]=min(f[i][j],f[i][k]+f[k][j]);

不判断i,j,k是否相等也不会影响结果的正确性.当然i,j,k出现相等时这样的转移没有什么实际意义.

如何初始化?如果i到j有一条长度为w的边那么我们把f[i][j]赋值为w.如果i到j没有边我们将f[i][j]赋值为inf,认为从i到j有一条长度大到不影响结果的边(inf是一个对于数据范围来说足够大的值.当用int存储f[i][j]的时候inf常用0x3f3f3f3f.如果将inf取值为0x7f7f7f7f,将容易导致int加法溢出).

f[i][i]如何初始化?实际上,将f[i][i]初始化为任何值都不会影响floyd算法的正确性.为了统一性起见,一般把f[i][i]初始化为0.从i出发不需要走任何边就能到达i.

计算从i到j的长度等于最短路的路径条数g[i][j]?bzoj1491[NOI2007]社交网络

定义g[k][i][j]表示从i到j,允许经过编号小于等于k的点,长度等于f[k][i][j]的路径条数,转移的时候需要考虑f[k][i][j]的数值是否等于f[k+1][i][j]然后进行讨论.g[k][i][j]也可以变成二维数组g[i][j].

dp的顺序一定是从1到n吗?luogu2966[USACO09DEC]牛收费路径

实际上我们枚举k的顺序可以改变,例如随便取一个1到n的排列,定义f[k][i][j]为允许以排列中前k个点作为中转点时i到j的最短路.对于Tolls这个题就是按照点权顺序.

求有向图中的最小环?(一个边权和最小的回路)vijos1423最佳路线

环上至少有两个点.枚举i,j,用f[i][j]+f[j][i]更新答案即可.如果必须经过点1,那么用f[1][i]+f[i][1]更新答案.(必须经过点1的时候,其实只需在原图和所有边反向的图上各从1出发跑一遍dijkstra)

求无向图最小环?(不允许重复经过同一条边,例如从1走到2再从2走回1不是一个环)

不能直接套用有向图最小环算法.

由于无向图中的最小环至少包含三个点,所以我们可以O(n^3)枚举三个点:首先枚举环中编号最大的点k然后枚举和k相邻的两个点i,j(要求k,i之间,k,j之间必须有边).那么i和j之间怎样连接?因为我们需要让k成为编号最大的点,那么i和j之间的路径长度只能是f[k][i][j].因此我们在floyd枚举的过程中更新到f[k][i][j]时统计以k作为编号最大的点的最小环.

floyd最短路的更多相关文章

  1. Floyd最短路算法

    Floyd最短路算法 ----转自啊哈磊[坐在马桶上看算法]算法6:只有五行的Floyd最短路算法 暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计 ...

  2. 【啊哈!算法】算法6:只有五行的Floyd最短路算法

            暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计划旅程,小哼希望在出发之前知道任意两个城市之前的最短路程.         上图中有 ...

  3. 【坐在马桶上看算法】算法6:只有五行的Floyd最短路算法

            暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计划旅程,小哼希望在出发之前知道任意两个城市之前的最短路程.         上图中有 ...

  4. BZOJ1491: [NOI2007]社交网络(Floyd 最短路计数)

    Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 2343  Solved: 1266[Submit][Status][Discuss] Descripti ...

  5. Wikioi 1020 孪生蜘蛛 Label:Floyd最短路

    题目描述 Description 在G城保卫战中,超级孪生蜘蛛Phantom001和Phantom002作为第三层防卫被派往守护内城南端一带极为隐秘的通道. 根据防护中心的消息,敌方已经有一只特种飞蛾 ...

  6. FZU2090 旅行社的烦恼 巧妙floyd 最短路

    分析:floyd看似很好理解,实际上是状态转移,具体的解释参照这里 http://www.cnblogs.com/chenying99/p/3932877.html 深入理解了floyd后,这个题就可 ...

  7. 只有五行的Floyd最短路算法

            暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计划旅程,小哼希望在出发之前知道任意两个城市之前的最短路程.         上图中有 ...

  8. 仅仅有五行的Floyd最短路算法

    暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,例如以下图.为了节省经费以及方便计划旅程,小哼希望在出发之前知道随意两个城市之前的最短路程. 上图中有4个城市8条公路,公路上的数 ...

  9. BZOJ 1491 社交网络 Floyd 最短路的数目

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1491 题目大意: 见链接 思路: 直接用floyd算法求最短路,同时更新最短路的数目即 ...

随机推荐

  1. 20155316 2016-2017-2 《Java程序设计》第2周学习总结

    教材学习内容总结 学习主要内容:基本类型介绍及流程控制简介 关键点:关键记住JAVA的大体框架,可以类比C语言结合着记.相较于C不同且值得关注的主要信息有: 基本类型的不同:byte.boolean. ...

  2. 20145226夏艺华 《Java程序设计》第9周学习总结

    教材学习内容总结 学习目标 了解JDBC架构 掌握JDBC架构 掌握反射与ClassLoader 了解自定义泛型和自定义枚举 会使用标准注解 第16章 整合数据库 16.1 JDBC入门 (一)JDB ...

  3. vim 中文乱码问题

    编辑~/.vimrc文件,加上如下几行: set fileencodings=utf-8,ucs-bom,gb18030,gbk,gb2312,cp936   set termencoding=utf ...

  4. RHCSA-day4

    硬盘分区 1.硬盘的物理组成 硬盘实际上是由很多的盘片.磁臂.磁头与主轴马达所组成的. 那么实际的数据当然是写在具有磁性物质的盘片上了.数据的读写主要是通过在磁臂上的磁头来完成的.实际运转时,主轴马达 ...

  5. sql异常 获取数据失败的原因及解决方案

    使用dbutils工具类时 不能使用char作为sql的字段类型 报错提示不能转换 所以替换成别的(一般是String)即可

  6. C#实现仪器的自动化控制

    1.概述 生产测试当中,测试仪器不可或缺,如果是小规模生产,手动测试可以对付:但是要想到达大批量生产的目的,为了简化测试,节约时间,就需要进行自动化测试.出于这样的需求,对仪器的自动化程控就有了需求. ...

  7. 【MySQL安装】MySQL5.6在centos6.4上的安装

    卸载原来安装的mysql 安装从官网下载的mysql rpm包 发现有依赖,需要先安装libaio包和libnuma包 再装mysql就可以了 安装客户端 安装完成后,启动mysql 但是发现用没有m ...

  8. Mac 必备工具之 brew

    brew 是 Mac 下的一个包管理工具,类似于 centos 下的 yum,可以很方便地进行安装/卸载/更新各种软件包,例如:nodejs, elasticsearch, kibana, mysql ...

  9. nexus实现从windows迁移至Linux平台

    说明: 由于老环境是在本地windows 2008 R2里面搭建的nexus,前面搭建了jenkins,需要将maven私库迁移至云服务器的CentOS 7系统下,之前没做过nexus的迁移,在网上看 ...

  10. DeepLearning - Overview of Sequence model

    I have had a hard time trying to understand recurrent model. Compared to Ng's deep learning course, ...