是真懂还是假懂?

Floyed算法:是最短路径算法可以说是最慢的一个。

原理:O(n^3)的for循环,对每一个中间节点k做松弛(寻找更短路径);
但它适合算多源最短路径,即任意两点间的距离。
但spfa,迪杰斯特拉就只能算一个点到其他任一点的最短路径。
 
关键在于,我们真的真正理解floyed吗?
 
就是因为它太短了,以至于我们有些人(神仙除外)看代码后看到这样一个语句:
 
d[i][j]=min(d[i][j],d[i][k]+d[k][j])
 
也就是说,对于每一个中转点k来说,进行O(n^2)的松弛,一定能找到最短路径。
 
虽不是最优,但是松弛次数来凑!
 
这大概就是我们(之前的我)的无须证明的,想当然的理解,并背下来了它,以便以后想TLE时用。(???O(n^3));
so?
Floyed本质是dp;
 
递推公式:(图片源自网络大佬)

众所周知,dp(动态规划)要满足无后效性。也就是说。。。。。。

还是先举个例子:

我们设k取某一个k1时满足k1为最终点i到j最短路经过的点,但是在外层循环到k1时d[i][k1]和d[k1][j]并没有取到最小值,因为k1只能取一次,那么往后再循环是不是就取不到k1了呢??

答案当然不是的(不然这个算法为什么正确?)

还是那句话,dp无后效性,

也就是说,k不单单是枚举,还是一个状态变量,找i和j之间通过编号不超过k(k从1到n)的节点的最短路径(一定要注意,这里是当前最短路径,

k之前的已经变成最短路了,对于每一个k,我们都进行了n^2的充分枚举(ij),已保证当前已经满足对从1到k的节点最优,

那么当k枚举完所有点,那么一定是最优的了

换句话说,在d[i][j]=min(d[i][j],d[i][k]+d[k][j])

公式中,因为k之前已经作为i或者j被枚举过了;,d[i][k]和d[k][j] 已经被1到k枚举过了

那么他们一定是1到k节点中最优的路径,等枚举到n时,所有的都枚举完了,那么它们就是
 
基本代码:
 
for(k=;k<=n;k++) //中转节点
for(i=;i<=n;i++) 第二层循环
for(j=;j<=n;j++) 第三层循环
if(e[i][j]>e[i][k]+e[k][j] )如果直接到达比通过k这个中转接点到达的距离短
e[i][j]=e[i][k]+e[k][j];那么就更新松弛

算法复杂度O(n^3),这也是为什么平常很少使用的原因。

例题校内题目:

城市交通费
【问题描述】
有 n 个城市,编号 1~n。其中 i 号城市的繁华度为 pi。省内有 m 条可以双向同行的高速
公路,编号 1~m。编号为 j 的高速公路连接编号为 aj 和 bj 两个城市,经过高速公路的费用
是 wj。若从城市 x 出发到某城市 y,除了需要缴纳高速公路费用,还要缴纳“城市建设费”
(为从 x 城市到 y 城市所经过的所有城市中繁华度的最大值,包括 x 和 y 在内)。
现提出 q 个询问,每个询问给出一组 x 和 y,你需要回答从 x 出发到 y 城市,所需要的
最低交通费(高速公路费+城市建设费)是多少。
【输入】
第一行三个整数 n,m,q。
第二行 n 个整数,表示 p1~pn。
接下来 m 行中,每行 3 个正整数,第 j 行包含 Aj,Bj,Wj。
随后 Q 行每组两个正整数 x,y 表示一组询问。
【输出】
共 Q 行,为对 Q 个问题的回答:x 城市到 y 城市的最小交通费用。
【样例输入】
5 7 2
2 5 3 3 4
1 2 3
1 3 2
2 5 3
5 3 1
5 4 1
2 4 3
3 4 4
1 4
2 3
【样例输出】
8
9
【数据范围及约定】
n≤250,m≤20000,Q≤10000,Pi≤10000,Wj≤2000,保证任意两个城市可以互相到达。
【样例说明】
图中,代表城市的格子中第一个数字是城市编号,第二个红色数字是该城市的繁华度。
(1)从城市 1 到城市 4 的最小交通费用路线是:1 3 5 4;公路费是 2+1+1=4;城市建设费是
max{2,3,4,3}=4;总交通费用 4+4=8。
(2)从城市 2 到城市 3 的最小交通费用路线是:2 5 3;公路费是 3+1=4;城市建设费是
max{5,4,3}=5;总交通费用 4+5=9。

这个题看起来就是一个最短路问题。
 
问题是Q(询问次数)的范围到了一万,一万次询问,不管是spfa还是堆优化迪杰斯特拉,都得爆炸。
 
那么,我们平时鸟都不鸟的Floyed就排上了用场;
 

但题目中给的点数为250,三次方为15625000,不会爆TLE,

可以使用,对于一万次询问,O(1)询问就可以过了。

但是,这个题目有一个附加条件:繁华度。

怎样在floyed算法中加入繁华度来考虑呢?

代码:(注意floyed部分)

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
int n,m,q,p[],aj,bj,wj,x,y,f[][],a[][],top,t[];
int cmp(int x,int y)
{
return p[x]<p[y];
}
int main()
{
memset(a,,sizeof(a));
top=;
scanf("%d%d%d",&n,&m,&q);
for(int i=;i<=n;i++)//正常输入
scanf("%d",&p[i]);
for(int i=;i<=m;i++)
{
scanf("%d%d%d",&aj,&bj,&wj);
a[aj][bj]=min(a[aj][bj],wj);//初始化
a[bj][aj]=min(a[bj][aj],wj);//这是邻接矩阵类型的,没用链式前向星
}
for(int i=;i<=n;i++)
{
a[i][i]=;//对角线置为0
t[i]=i;//编号
}
sort(t+,t++n,cmp);//t数组开始时是编号,但经过sort排序后就变成了城市繁华度从小到大的顺序
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
f[i][j]=a[i][j]+max(p[i],p[j]);//f数组即为答案数组,这里初始化
for(int k=;k<=n;k++)
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
{
a[i][j]=min(a[i][j],a[i][t[k]]+a[t[k]][j]);//a数组就是最短路数组
f[i][j]=min(f[i][j],a[i][j]+max(p[i],max(p[j],p[t[k]])));
f数组就是答案数组,a数组不受f数组影响,有可能a更新了,但是f将最大繁华值考虑进去后并没有更新,那么a数组保留最短路为以后的更新做铺垫
}
for(int i=;i<=q;i++)
{
scanf("%d%d",&x,&y);
printf("%d\n",f[x][y]);
}
return ;
}

Floyed(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. Floyd算法详解

    Floyd本质上使用了DP思想,我们定义\(d[k][x][y]\)为允许经过前k个节点时,节点x与节点y之间的最短路径长度,显然初始值应该为\(d[k][x][y] = +\infin (k, x, ...

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

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

  6. kmp算法详解

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

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

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

  8. [转] KMP算法详解

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

  9. 【转】AC算法详解

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

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

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

随机推荐

  1. C#析构函数(destructor)和终结器(Finalizer) .

    使用析构函数释放资源 析构函数用于析构类的实例. 1)         不能在结构中定义析构函数.只能对类使用析构函数. 2)         一个类只能有一个析构函数. 3)         无法继 ...

  2. Dapper 多表(三表以上)查询小技巧

    在使用Dappr做查询的时候遇到多表查询,之前多是两张表,现在出现三张表或者更多.两表的时候使用splitOn进行分割,splitOn的默认值是Id.在我建库的时候,主键ID并不都是这个名字.当出现三 ...

  3. beego 如何自定error

    beego通过Redirect方法来进行跳转: 1 2 3 func (this *AddController) Get() {     this.Redirect("/", 30 ...

  4. 惊讶!我定的日志规范被CTO在全公司推广了

    打印日志是一门艺术,但长期被开发同学所忽视.日志就像车辆保险,没人愿意为保险付钱,但是一旦出了问题都又想有保险可用.我们打印日志的时候都很随意,可是用的时候会吐槽各种 SB 包括自己!写好每一条日志吧 ...

  5. PJzhang:关闭wps小广告和快速关闭445端口

    猫宁!!! ​​   kali linux上安装的wps,没有广告,而且轻巧简洁.   如果你在windows上安装wps,除了ppt.word.excel,还会有一个h5的应用,当然,最令人烦扰的当 ...

  6. Emgu 学习之HelloWorld

    安装和配置 系统Win10,VS2013,下载Emgu安装包libemgucv-windesktop-3.4.3.3016 安装到了E:\OpenCV\emgucv-windesktop 3.4.3. ...

  7. [c++] 链表各类操作详解

    链表概述 链表是一种常见的重要的数据结构.它是动态地进行存储分配的一种结构.它可以根据需要开辟内存单元.链表有一个“头指针”变量,以head表示,它存放一个地址.该地址指向一个元素.链表中每一个元素称 ...

  8. iframe在firefox下的无法正常target问题

    今日在改一个网站的时候碰到个奇葩的问题. 把网站按照结构划分,做了个主页面,嵌入iframe,设定该iframe的name,主页面上的链接使用target保证在iframe中打开该链接. 听上去很常规 ...

  9. sql server2012中使用convert来取得datetime数据类型样式(全)

    一.日期数据格式的处理,两个示例: CONVERT(varchar(16), 时间一, 20) 结果:2007-02-01 08:02/*时间一般为getdate()函数或数据表里的字段*/ CONV ...

  10. 在字符串中找出第一个只出现一次的字符,Python实现

    要求: 1. 不能依赖库函数直接实现此功能,需使用基础的数据结构实现 2. 时间复杂度 O(n) 思路: 1. 用字典存储每个字符在字符串中出现的次数 2. 列表是有序的,用来存储字符的出现先后 3. ...