最短路径——Floyd算法(含证明)
通过dij,ford,spfa等算法可以快速的得到单源点的最短路径,如果想要得到图中任意两点之间的最短路径,当然可以选择做n遍的dij或是ford,但还有一个思维量较小的选择,就是floyd算法。
多源最短路径算法
Floyd算法
思维
先直观做个思考,一张图,任意两个点,已知两点间的路径权值,如果在图中能够找到一个点插入到这两点的路径之中,使得构成的路径权值小于之前的路径权值。就可以认为这条路比之前的路更短,这个点是属于两点间最短路径的。由此可以得到一个递推公式:
\]
问题就转换成了e[u][k],e[k][v]最短路径的问题,这就是一种动态规划。
只要把图枚举一遍就可以得到所有点之间的最短路径:
for (int k = 1; k <= n; k++)
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
e[i][j] = min(e[i][j], e[i][k] + e[k][j]);
说到动态规范,总会感叹递推式的优美,但是有没有想过,为什么k循环在最外层,而且由于e[i][k],e[k][j]也是在不断更新,而不是恒定的最小值,所以如何保证算法在最后一次松弛更新的时候,e[i][k],e[k][j]一定是最小的。
我们用归纳法(一生之敌)做一次证明:
- 不妨做个命题:假设任意两点i和j之间的路径上可选择经过的结点集合中,座号最大的是x,当k=x的时候,d[i][j]得到最小值。
- 当i,j两点之间路径可选择经过结点仅有一个点时候,命题是成立的。
- 设i-x中座号最大的为x1,x-j中座号最大的为x2。
- 显然x>x1,x>x2。
- 假设此时命题成立,则k=x1时,d[i][x]最小,k=x2时,d[x][j]最小。
- 由此可以得到k=x的时候d[i][x]+d[x][j]已经是最小了,那么e[i][j]=min(e[i][j],e[i][x]+e[x][j])必然可以得到最小值。
由此可以证明在k循环完后就能够得到最小的。当然也可以画张图直观的感受一下。
代码实现
#include<iostream>
#include<algorithm>
using namespace std;
const int MAX = 1000;
int e[MAX][MAX];
int n, m;
void Floyd() {
for (int k = 1; k <= n; k++)
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
e[i][j] = min(e[i][j], e[i][k] + e[k][j]);
}
int main() {
cin >> n >> m;
const int inf = 100000;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
if (i == j) e[i][j] = 0;
else e[i][j] = inf;
int u, v, w;
for (int i = 0; i < m; i++) {
cin >> u >> v >> w;
e[u][v] = w;
e[v][u] = w;
}
Floyd();
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
cout << e[i][j] << " ";
return 0;
}
最短路径——Floyd算法(含证明)的更多相关文章
- 单源最短路径Dijkstra算法,多源最短路径Floyd算法
1.单源最短路径 (1)无权图的单源最短路径 /*无权单源最短路径*/ void UnWeighted(LGraph Graph, Vertex S) { std::queue<Vertex&g ...
- 7-8 哈利·波特的考试(25 分)(图的最短路径Floyd算法)
7-8 哈利·波特的考试(25 分) 哈利·波特要考试了,他需要你的帮助.这门课学的是用魔咒将一种动物变成另一种动物的本事.例如将猫变成老鼠的魔咒是haha,将老鼠变成鱼的魔咒是hehe等等.反方向变 ...
- 单源最短路径——Floyd算法
正如我们所知道的,Floyd算法用于求最短路径.Floyd算法可以说是Warshall算法的扩展,三个for循环就可以解决问题,所以它的时间复杂度为O(n^3). Floyd算法的基本思想如下:从任意 ...
- 最短路径Floyd算法【图文详解】
Floyd算法 1.定义概览 Floyd-Warshall算法(Floyd-Warshall algorithm)是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权的最短路径问题,同时也被 ...
- 最短路径—Floyd算法
Floyd算法 所有顶点对之间的最短路径问题是:对于给定的有向网络G=(V,E),要对G中任意两个顶点v,w(v不等于w),找出v到w的最短路径.当然我们可以n次执行DIJKSTRA算法,用FLOYD ...
- 最短路径--Floyd算法
Floyd算法 1.定义概览 Floyd-Warshall算法(Floyd-Warshall algorithm)是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权的最短路径问题,同时也被 ...
- 最短路径(Floyd)算法
#include <stdio.h>#include <stdlib.h>/* Floyd算法 */#define VNUM 5#define MV 65536int P[VN ...
- 【最短路径Floyd算法详解推导过程】看完这篇,你还能不懂Floyd算法?还不会?
简介 Floyd-Warshall算法(Floyd-Warshall algorithm),是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法,与Dijkstra算法类似.该算法名称以 ...
- 图论之最短路径floyd算法
Floyd算法是图论中经典的多源最短路径算法,即求任意两点之间的最短路径. 它可采用动态规划思想,因为它满足最优子结构性质,即最短路径序列的子序列也是最短路径. 举例说明最优子结构性质,上图中1号到5 ...
随机推荐
- 在Win7虚拟机下搭建Hadoop2.6.0伪分布式环境
近几年大数据越来越火热.由于工作需要以及个人兴趣,最近开始学习大数据相关技术.学习过程中的一些经验教训希望能通过博文沉淀下来,与网友分享讨论,作为个人备忘. 第一篇,在win7虚拟机下搭建hadoop ...
- Data Guard 知识 (来自网络)
更改DG工作模式前提参数得设定合理. Physical standby直接从主库接受archived log,然后直接做基于block的物理恢复(更新或调整变化的block),所以physical s ...
- springboot中有用的几个有用aware以及bean操作和数据源操作
本文参考了: https://blog.csdn.net/derrantcm/article/details/76652951 https://blog.csdn.net/derrantcm/arti ...
- Tornado异步之-协程与回调
回调处理异步请求 回调 callback 处理异步官方例子 # 导入所需库 from tornado.httpclient import AsyncHTTPClient def asynchronou ...
- Nodejs 使用 addons 调用c++ 初体验(一)
纠结很久,决定写一点遇到的“坑”. 基础环境:win7-64bit node(v7.5.0) 这些安装实在是太方便了,自行准备吧. 1. 安装 python(2.7.x ),用npm安装 nod ...
- python基础数据类型的相关知识点
1.字符串的函数join >>> s = "Hello" >>> s1 = s.join("你好")#将字符串Hello插入 ...
- discuzX3.2 X3.4网站漏洞修复 SQL注入与请求伪造攻击利用与修复
2018年12月9日,国内某安全组织,对discuz X3.2 X3.4版本的漏洞进行了公开,这次漏洞影响范围较大,具体漏洞是discuz 的用户前段SQL注入与请求伪造漏洞,也俗称SSRF漏洞,漏洞 ...
- Node.js中的不安全跳转如何防御详解
Node.js中的不安全跳转如何防御详解 导语: 早年在浏览器大战期间,有远见的Chrome认为要运行现代Web应用,浏览器必须有一个性能非常强劲的Java引擎,于是Google自己开发了一个高性能的 ...
- mac制作U盘启动器
Infi-chu: http://www.cnblogs.com/Infi-chu/ 一.所需工具及必要条件: 1. 首先需要一个大于16GB U盘. 2.电脑系统版本应该大于10.11.X(因为之前 ...
- Kubernetes-DNS
Kubernetes提供的虚拟DNS服务名为skydns,由四个组件组成: etcd:DNS存储 kube2sky:将Kubernetes Master中的Service(服务)注册到etcd sky ...