FLOYD 求最小环

摘要:
首先,让我们介绍FLOYD算法的基本思想。让我们假设d[i,j,k]只允许通过节点1……接下来,让我们通过几个例子来看看FLOYD算法的魔力。但是FLOYD算法可以在O(n^3)中很容易地解决这个问题。对于这个问题,除了上面提到的SPFA点分割方法,FLOYD也可以很好地解决它。首先,“密度”非常特殊。IJ之间的最小密度路径和JK之间的最小路径不一定是IK之间的最小浓度路径。


首先 先介绍一下 FLOYD算法的基本思想

 

设d[i,j,k]是
在只允许经过结点1…k的情况下
i到j的最短路长度
则它有两种情况(想一想,为什么):
最短路经过点k,d[i,j,k]=d[i,k,k-1]+d[k,j,k-1]
最短路不经过点k,d[i,j,k]=d[i,j,k-1]
综合起来: d[i,j,k]=min{d[i,k,k-1]+d[k,j,k-1],d[i,j,k-1]}
边界条件: d[i,j,0]=w(i,j)(不存在的边权为∞

floyd算法的流程:
把k放外层循环,可以节省内存
对于每个k,计算每两点的目前最短路
代码(需记忆)
for k:=1 to n do
for i:=1 to n do
  for j:=1 to n do
    if (d[i,k]<∞)and(d[k,j]<∞)
       and(d[i,k]+d[k,j]<d[i,j]) then
          d[i,j]:=d[i,k]+d[k,j]               (以上2段引自刘汝佳的课件)
时间复杂度:O(n^3)
FLOYD算法的复杂度虽然是O(n^3)但是它计算出任意一对点之间的最短路。
FLOYD的代码具有一种简洁美,当时间不允许写其他算法时的时候,写一个FLOYD,骗一部分的分,也是一个不错的选择。
另一方面,它不怕负权边,也可以判断负权回路。

接下来通过几个例题让我们看看FLOYD 算法的神奇威力。
第一. 求最小环
有向图的最小环和无向图的最小环完全是两种不一样的问题。
其一般解法都是枚举一条边uv删除,然后求一条uv间的最短路径(假设长S)然后用S+边uv的长,来更新答案。
如果用SPFA来求最短路,那么复杂度是O(m*km) k的取值取决于 图本身。
但是FLOYD算法可以在O(n^3)内很轻松地解决这个问题。
首先对于有向图
 由于一条边UV只能从U到V,而不能逆行之,那么我们只需要更新出图中任意2个点之间的最短路径。
记F[U,V]表示U到V的最短距离
G[U,V] 是原图中U到V的边的长
对于每对(U,V)我们只要将G[U,V]+F[V,U]来更新答案就行了。
无向图的最小环相对麻烦一些。
因为我们要避免一条无向边被2次走过(被当做2条边)的情况。
FOR EXAMPLE
u v之间有且只有一条边e   我们大可以从U 走到V 然后从V走回U  但是这并不是一个环
算法:
在floyd的同时,顺便算出最小环
   g[i][j]=(i,j之间的边长)
   dist:=g;
   for k:=1 to n do
    begin
      for i:=1 to k-1 do
        for j:=i+1 to k-1 do
            answer:=min(answer,dist[i][j]+g[i][k]+g[k][j]);
      for i:=1 to n do
         for j:=1 to n do
             dist[i][j]:=min(dist[i][j],dist[i][k]+dist[k][j]);
    end;
   关于算法<2>的证明:
    一个环中的最大结点为k(编号最大),与他相连的两个点为i,j,这个环的最短长度为g[i][k]+g[k][j]+i到j的路径中,所有结点编号都小于k的最短路径长度
    根据floyd的原理,在最外层循环做了k-1次之后,dist[i][j]则代表了i到j的路径中,所有结点编号都小于k的最短路径
    综上所述,该算法一定能找到图中最小环。

第二.求经过K条边的最短路径
例题:给出了一张有N个点M条边的加权有向无环图,接下来有Q个询问,每个询问包括2个节点X和Y,要求算出从X到Y的一条路径,使得密度最小(密度的定义为,路径上边的权值和除以边的数量)。
 有1 ≤ N ≤ 50,1 ≤ M ≤ 1000,1 ≤ W ≤ 100000,1 ≤ Q ≤ 100000
这道题十分坑爹。
题目里说好是无环图,但是数据里到处都是环。
我刚开始想的方法是用SPFA拆点做
把原图中每个点拆成N-1个点,分别表示经过I条边到达的这个点。因为最多经过N-1条边。
数据中这种环就会像负权环一样导致SPFA永远做下去。

但是暂且不管数据如何。对于这个题目,除了上面讲的SPFA 拆点的做法,FLOYD 也是可以很好解决的
首先这个“密度”很特殊,IJ之间最小密度路径加上JK之间最小路径,不一定就是IK之间的最小密度路径。
所以我们要先枚举经过了P条边 (1<=P<=N-1)

定义状态f(i,j,k)表示从i到j恰好经过k条边的最短路,类似Floyd的算法得出DP方程:
        f(i,j,k)=Min{f(i,h,g)+f(h,j,k-g)}。
这个方程是5维的,会超时,如何减小维数呢?
考虑在何处重复决策。注意到f(i,j,k)的选择路径V1-V2-...-Vk,实际上我们只要找到这里的一个点决策即可,而不需每个点都判断过去。这样就很容易想到在最后一个点进行决策。
        f(i,j,k)=Min{f(i,h,k-1)+f(h,j,1)}。
这样这个方法的时间复杂度就是0(N^4) 空间复杂度O(N^3)
问题得到了很好的解决。


免责声明:文章转载自《FLOYD 求最小环》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Trie树(前缀树)Idea 常用快捷键列表下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Akamai在内容分发网络中的算法研究(翻译总结)

BLOOM FILTERS Bloom filters的研究主要用在akamai的CDN中的两个场景:1)索引管理优化;2)内容过滤。 Bloom filters是hash算法的一个变种,有非常优秀的空间效率(使用位数组)和时间效率(插入的时间复杂度稳定为常数),但是会有一定的错误率。直观的说,bloom算法类似一个hash set,用来判断某个元素(ke...

国家集训队论文分类整理(转)

距离ACM/ICPC的时间越来越少了,选择性地看一些集训队论文是很有必要的。 (在此给已经看过所有论文的神牛跪了= =)http://www.cnblogs.com/AbandonZHANG/archive/2012/07/21/2601889.html 所以,我在此整理了一下,供大家参考。 组合数学 计数与统计 2001 - 符文杰:《P...

Java技术栈

内容: 1、Java基础(JavaSE) 2、数据结构与算法与设计模式 3、计算机理论知识 4、数据库 5、Java web(JavaEE) 6、消息队列 7、Linux及服务器相关 8、分布式相关 9、拓展技能 参考:https://blog.csdn.net/ferrari_cal/article/details/79093826 以下整理结合个人实际...

密码算法详解——AES

0 AES简介   我们知道数据加密标准(Data Encryption Standard: DES)的密钥长度是56比特,因此算法的理论安全强度是256。但二十世纪中后期正是计算机飞速发展的阶段,元器件制造工艺的进步使得计算机的处理能力越来越强,DES将不能提供足够的安全性。1997年1月2号,美国国家标准技术研究所(National Institut...

算法&amp;gt;并行算法

并行算法 一、并行算法 什么是并行算法? 它可理解为: 适合于在某类并行计算机上求解问题和处理数据的算法, 是一些可同时执行的诸进程的集合, 这些进程相互作用和协调作用, 从而达到对给定问题的求解。 二、并行计算机 并行处理就是把一个传统串行处理的任务分解开来, 并将其分配给多个处理器同时处理, 即在同一时间间隔内增加计算机的操作数量。为并行处理所设计的计算...

科码先锋面试

视频面试,先做简短的自我介绍,然后结合项目和简历问了些问题 过了几道之前做的笔试题(有一道电商经典题,创建订单的过程需要操作多张表,时间过长导致数据库阻塞严重,让你优化避免这个问题 网上查到的事务调优 https://juejin.im/post/6860774571088773128)说下双向链表的结构(说了链表有结点,结点里定义了值、前置结点、后...