算法之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:已求出的顶点的 ...
随机推荐
- 5.@pytest.mark.parametrize()数据驱动
简介: pytest.mark.parametrize 是 pytest 的内置装饰器,它允许你在 function 或者 class 上定义多组参数和 fixture 来实现数据驱动. @pytes ...
- 一文理解Cookie、Session
一文理解Cookie.Session 1.什么是会话 用户打开浏览器,点击多个超链接,访问服务器的多个web资源,然后关闭浏览器,整个过程就称为一个会话: HTTP 是无状态,有会话的 HTTP 是无 ...
- Jmeter之聚合报告“造假”
通过Jmeter,模拟一个"虚假"的聚合报告,可"应付"日常现场项目的性能测试验收.本文档着重介绍jmeter的固定定时器,通过设置随机的延迟时间(如想业务场景 ...
- tool1
//导出 public void excel(List<Long> ids, HttpServletResponse response) { List<StockPageVo> ...
- C#使用内存和指针方式将字节数组转换为Bitmap
/// <summary> /// 指针方式转 /// </summary> /// <param name="Width">图像的宽</ ...
- C#自定义控件开发(1)
自定义控件可以用组件或者用户控件来开发,如果是基于基础控件,进行一些扩展,那么可以使用组件,其它的情况可以使用用户控件. 首先新建一个类库项目,然后添加一个组件,取名为ButtonExtend,再添加 ...
- Vue 基础学习总结
介绍 Vue.js 中文文档地址:https://cn.vuejs.org/guide/introduction.html#what-is-vue Vue.js 是什么 Vue (读音 /vjuː/, ...
- docker使用bind9实现域名解析
目录 刷新服务 修改配置文件 从 114 缓存 查询 数据 可以 dig 无法 ping 查看 已经 区域 解析,并添加 新的 解析 项 在 linux 安装 局域网 cert rndc 查看 默认的 ...
- 【Docker】容器使用规范--安全挂载建议
容器挂载过程和安全挂载建议 绑定挂载 本文所提到的挂载主要指绑定挂载(bind mount),即通过-v /xx/xx:/xx/xx 和 --mount type=bind,xxx,xxx两种方式设置 ...
- Kubernetes安装GitLab
个人名片: 对人间的热爱与歌颂,可抵岁月冗长 Github:念舒_C.ying CSDN主页️:念舒_C.ying 个人博客 :念舒_C.ying Kubernetes安装GitLab Step 1 ...