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. WPF MVVM从入门到精通5:PasswordBox的绑定

    原文:WPF MVVM从入门到精通5:PasswordBox的绑定   WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通2:实现一个登录窗口 WPF MVVM从入门到精通 ...

  2. day 5 多态 类 静态

    1.多态 执行的时候才知道调用谁 class Dog(object): def print_self(self): print("大家好,我是来自西安的小白") class Xia ...

  3. 洛谷P2831 愤怒的小鸟

    洛谷P2831 愤怒的小鸟 原题链接 题解 首先简单数学公式送上. \(ax_1^2+bx_1=y_1\) \(ax_2^2+bx_2=y_2\) \(ax_1^2x_2+bx_1x_2=y_1x_2 ...

  4. HTML基本代码教学,第三天

    HTML 今天由于个人情况,身体不适,但是为了大家的学习进度,咱们以纯文字得形式来简单了解下今天的学习内容 今儿咱们来了解下表单 <form id=" "  name=&qu ...

  5. NLP的12条精髓

    NLP是神经语言程序学 (Neuro-Linguistic Programming) 的英文缩写.一.没有两个人是一样的 No two persons are the same. 1.没有两个人的人生 ...

  6. VirtualBox主机和虚拟机互相通信

    默认情况下VirtualBox虚拟机网络设置为网络地址转换,虚拟机中的地址一般是10.0.2.x,虚拟机中访问主机只需要访问默认网关地址即可,但是主机访问虚拟机就需要增加一些配置了,方法有以下几种: ...

  7. grep 文件内容搜索

    比如现在我们要查找在/home/userlan/目录中哪些文件中包含foobar这个关键字 1. 打开终端2. 输入命令 grep -rl "foobar" /home/userl ...

  8. charles基本使用文档

    Charles 主要的功能包括: 截取 Http 和 Https 网络封包. 支持重发网络请求,方便后端调试. 支持修改网络请求参数. 支持网络请求的截获并动态修改. 支持模拟慢速网络. Charle ...

  9. sublime3配置java开发环境

    链接:http://www.jianshu.com/p/48a524a4f63c 或者:http://www.jianshu.com/p/9d167c4c4feb 侵权删!

  10. 423. Valid Parentheses【LintCode java】

    Description Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine ...