算法之Floyd-Warshall算法【c++】【图论】【最短路】
我们作为刚学图论的小蒟蒻,先接触到的算法一定是图上最短路径算法。而最短路算法中最简单的当属Floyd-Warshall算法。下面是一些基本介绍:
该算法可以计算图上任意两点间的最短路径
时间复杂度:O(n^3)
适用情况:适用出现负边权的情况
算法伪代码:
弗洛伊德算法的基本思想是动态规划,我们枚举每一个点,并以其为中间节点更新任意两点间的最小距离,伪代码:
#define maxn 最大节点数
#define inf 0x7fffffff-2
long long val[maxn][maxn];
long long dis[maxn][maxn];
inline void floyd(){
for(int i=1;i<=maxn;i++)
for(int j=1;j<=maxn;j++)
if(val[i][j])
dis[i][j]=val[i][j];
else
dis[i][j]=inf;
for(int k=1;k<=maxn;k++)
for(int i=1;i<=maxn;i++)
for(int j=1;j<=maxn;j++)
if(dis[i][j]>dis[i][k]+dis[k][j])
dis[i][j]=dis[i][k]+dis[k][j];
}
此时,dis[i][j]就是从i节点到j节点的最短路径。
算法分析&&思路讲解
- 初始化:我们在初始化时,将有边相连的节点间distance更新为边权值,无边相连直接设为极大值。
- 动态规划:对于每个节点,我们都让它做一次中间节点(k),然后分别枚举另外两个节点(i,j),如果当前从i到j的最短路大于从i到k的最短路加上从j到k的最短路,即从i到j如果经过k点会路径更短,那么我们更新从i到j的最短路。
- 算法结束,我们得到了所有的最短路。
需要强调的一点是,floyd中k的循环必须写在最外层,否则会导致动态规划状态转移发生错误!
例题讲解:Luogu P2935
传送门
不难发现,题目是让我们求所有牧场到喜欢的牧场的最短路,这就是所谓的多源最短路问题。对于这道题思路如下:
- 用floyd求出所有最短路。
- 枚举每个点,求出最小平均距离。
该题数据较小,这种思路完全可以通过。
代码:
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3fffffff
int n,m,f,u,v,t;
int square[501][501];
long long dis[501][501];
int like[501];
int main(){
scanf("%d %d %d",&n,&f,&m);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
dis[i][j]=inf;
}
dis[i][i]=0;
}//预处理。
for(int i=1;i<=f;i++){
scanf("%d",&like[i]);
}//输入每个喜欢的牧场
for(int i=1;i<=m;i++){
scanf("%d %d %d",&u,&v,&t);
dis[u][v]=t;
dis[v][u]=t;
}//输入牧场距离并预处理
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);//裸的floyd板子
}
}
}
int ans,maxx=inf,sum=0;
for(int i=1;i<=n;i++){
sum=0;
for(int j=1;j<=f;j++){
sum+=dis[i][like[j]];//统计从该节点到所有喜欢的牧场的总最短距离
}
if(sum<maxx){
ans=i;
maxx=sum;
}
//这里注意一下,题目说让我们求的是平均距离最小,但其实喜欢的牧场个数固定,我们就只需要求总最短路径最小就行了,不用再取平均值。
}
cout<<ans;//输出牧场序号
return 0;
}
拓展延伸:算法变形
floyd算法在一些情况下可以变形,用途是判断图上任意两点间连通性。
伪代码:
#define maxn 最大节点数
bool val[maxn][maxn];
bool dis[maxn][maxn];
inline void floyd(){
for(int i=1;i<=maxn;i++)
for(int j=1;j<=maxn;j++)
if(val[i][j])
dis[i][j]=1;//相邻两点间距离设为ture
else
dis[i][j]=0;//不相邻设为false
for(int k=1;k<=maxn;k++)
for(int i=1;i<=maxn;i++)
for(int j=1;j<=maxn;j++)
dis[i][j]=dis[i][j]||(dis[i][k]&&dis[k][j]);
//原理:若i与k联通,k与j联通,则i与j联通
}
完结撒花
算法之Floyd-Warshall算法【c++】【图论】【最短路】的更多相关文章
- Floyd—Warshall算法
我们用DP来求解任意两点间的最短路问题 首先定义状态:d[k][i][k]表示使用顶点1~k,i,j的情况下,i到j的最短路径 (d[0][i][j]表示只使用i和j,因此d[0][i][j] = c ...
- 图论之最短路径(1)——Floyd Warshall & Dijkstra算法
开始图论学习的第二部分:最短路径. 由于知识储备还不充足,暂时不使用邻接表的方法来计算. 最短路径主要分为两部分:多源最短路径和单源最短路径问题 多源最短路径: 介绍最简单的Floyd Warshal ...
- 图论——最短路径 Dijkstra算法、Floyd算法
1.弗洛伊德算法(Floyd) 弗洛伊算法核心就是三重循环,M [ j ] [ k ] 表示从 j 到 k 的路径,而 i 表示当前 j 到 k 可以借助的点:红色部分表示,如果 j 到 i ,i 到 ...
- 图论算法(二)最短路算法:Floyd算法!
最短路算法(一) 最短路算法有三种形态:Floyd算法,Shortset Path Fast Algorithm(SPFA)算法,Dijkstra算法. 我个人打算分三次把这三个算法介绍完. (毕竟写 ...
- WarShall算法
1.引言 图的连通性问题是图论研究的重要问题之一,在实际中有着广泛的应用.例如在通信网络的联通问题中,运输路线的规划问题等等都涉及图的连通性.因此传递闭包的计算需要一个高效率的算法,一个著名的算法就是 ...
- Gym 101873D - Pants On Fire - [warshall算法求传递闭包]
题目链接:http://codeforces.com/gym/101873/problem/D 题意: 给出 $n$ 个事实,表述为 "XXX are worse than YYY" ...
- 最小生成树(prime算法 & kruskal算法)和 最短路径算法(floyd算法 & dijkstra算法)
一.主要内容: 介绍图论中两大经典问题:最小生成树问题以及最短路径问题,以及给出解决每个问题的两种不同算法. 其中最小生成树问题可参考以下题目: 题目1012:畅通工程 http://ac.jobdu ...
- Floyd最短路径算法(来自微信公众号“算法爱好者”改编)
暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计划旅程,小哼希望在出发之前知道任意两个城市之前的最短路程. 上图中有4个城市8条公路,公路上的数字表 ...
- Floyd最短路径算法
看完这篇文章写的小程序,Floyd最短路径算法,求从一个点到另一个点的最短距离,中间可以经过其他任意个点.三个for循环,从i到j依次经过k的最短距离,最外层for循环是经过点K,内部两个循环是从i( ...
- C++编程练习(11)----“图的最短路径问题“(Dijkstra算法、Floyd算法)
1.Dijkstra算法 求一个顶点到其它所有顶点的最短路径,是一种按路径长度递增的次序产生最短路径的算法. 算法思想: 按路径长度递增次序产生算法: 把顶点集合V分成两组: (1)S:已求出的顶点的 ...
随机推荐
- 23.mixin类源码解析
mixin类用于提供视图的基本操作行为,注意mixin类提供动作方法,而不是直接定义处理程序方法 例如.get() .post(),这允许更灵活的定义,mixin从rest_framework.mix ...
- 8.DRF请求响应和api_view
一.请求对象(Request objects) DRF引入了一个扩展Django常规HttpRequest对象的Request对象,并提供了更灵活的请求解析能力 Request对象的核心功能是re ...
- 京东云开发者| Redis数据结构(二)-List、Hash、Set及Sorted Set的结构实现
1 引言 之前介绍了Redis的数据存储及String类型的实现,接下来再来看下List.Hash.Set及Sorted Set的数据结构的实现. 2 List List类型通常被用作异步消息队列.文 ...
- 前端性能优化——首屏时间&&白屏时间
1.首屏时间概念 首屏时间是指用户打开一个网站时,直到浏览器首页面内容渲染完成的时间. 2.白屏时间概念 白屏时间即是,浏览器开始显示内容的时间,所以我们一般认为解析完<head>的时刻, ...
- Mysql InnoDB Redo log
一丶什么是redo innodb是以也为单位来管理存储空间的,增删改查的本质都是在访问页面,在innodb真正访问页面之前,需要将其加载到内存中的buffer pool中之后才可以访问,但是在聊事务的 ...
- 【安装文档】TRex流量分析仪保姆级安装指南--基于VMware虚拟机(ubantu18.04@Intel 82545EM)
前言 既然你已经知道TRex并尝试搜索它的安装教程,这意味着你有一定的基础知识(至少知道自己需要什么).因此本文对于TRex的介绍部分会偏少 本次主要为TRex安装过程的一次记录(版本为v3.0.0) ...
- 嵌入式-C语言基础:函数指针
定义函数地址:如果在程序中定义了一个函数,那么在编译的时候,编译系统为函数代码分配一段存储空间,这段存储空间的起始地址(也叫入口地址)称为这个函数的地址. 和数组一样,数组名代表地址,而函数名表示函数 ...
- 第2-3-6章 打包批量下载附件的接口开发-文件存储服务系统-nginx/fastDFS/minio/阿里云oss/七牛云oss
目录 5.6 接口开发-根据文件id打包下载附件 5.6.1 接口文档 5.6.2 代码实现 5.6.3 接口测试 5.7 接口开发-根据业务类型/业务id打包下载 5.7.1 接口文档 5.7.2 ...
- WebApi如何启用Session并且使用
首先打开项目的Global.asax文件,重新方法init public override void Init() { //注册事件 this.AuthenticateRequest += WebAp ...
- java 分别获取当前时间的年月日以及当前时间所在周的周一周末日期
以前也经常用date去截取,但是病史所有场景都适合,或者说效率满足不了,或者说拼接格外麻烦.能用java本省的的方法去实现其实更爽.因为中西方的文化的差异有时候在简单的方法上我们不得不去加一些其他的去 ...