最近复习了下最短路,顺便写篇博客加强下自己的印象


1.Floyd算法
我认为是最短路最简单的算法,但一般来说简单的都不是什么好东西,因为复杂度比较高;

*核心思想
要缩短两点之间的距离,就需要第三个顶点来松弛。

*具体步骤
依次用1到n号顶点做中转,松弛任意两点之间的距离。

因为这个算法比较简单,就直接上代码了;

#include<iostream>using namespace std;const int N=2000;
int main()
{int maps[N][N];for(int i=1;i<=N;i++)for(int j=1;j<=N;j++){if(i==j)maps[i][j]=0;//起点和终点相同,路程为0elsemaps[i][j]=INT_MAX;//一开始没有路,则全部是无穷大}int n,m;//假设有n条路,m个城市cin>>n;int a,b,c;for(int i=1;i<=n;i++){cin>>a>>b>>c;maps[a][b]=c;maps[b][a]=c;//假设是双向路}for(int i=1;i<=m;i++)//枚举用来松弛的点for(int j=1;j<=m;j++)for(int k=1;k<=m;k++){if(maps[j][k]<maps[j][i]+maps[i][k]);//通过该点松弛后距离变小了maps[j][k]=maps[j][i]+maps[i][k];}cout<<maps[][]<<endl;//求得任意2点间的最短路
}

时间复杂度(o(m^3))
可以说对于百分之90的题 这个算法都是过不了的


2.Dijkstra算法
这个算法还是比较常用的,一定要掌握

*核心思想
通过“边”来松弛源点顶点到其余个顶点的路程

*具体步骤:

假设s是起点

寻找s集合到PQ集合最短的边

到2点的距离是最短的

接下来到6的距离是最短的

然后是7号点



(图片是学长那偷的)

这样s点到所有点的最短路就找出来了,我们来看看代码怎么写;(记住核心思想:通过“边”来松弛源点顶点到其余个顶点的路程)

#include<cstdio>
#include<queue>
#include<vector>
#include<iostream>
#define inf 0x3f3f3f
const int maxn=1005;
using namespace std;typedef pair<int,int> P; //前面放到 dis[i],后面放i struct node{int v,w;
}E;
vector<node> edge[maxn];
int dis[maxn];int main(){int n,m;int u;while(scanf("%d%d",&n,&m),n){//初始化for(int i=1;i<=n;i++){dis[i]=inf;} //存图 for(int i=1;i<=m;i++){scanf("%d%d%d",&u,&E.v,&E.w);edge[u].push_back(E);}priority_queue <P,vector<P>,greater<P> > que;while(!que.empty()) que.pop();dis[1]=0;que.push(P(dis[1],1));while(!que.empty()){P now=que.top(); que.pop();int nowu=now.second;for(int i=0;i<edge[nowu].size();i++){E=edge[nowu][i]; if(dis[E.v]>dis[nowu]+E.w){dis[E.v]=dis[nowu]+E.w;que.push(P(dis[E.v],E.v));}}}for(int i=1;i<=n;i++)printf("%d ",dis[i]);printf("\n");}return 0;
} /*
6 9
1 2 1
1 3 12
2 3 9
2 4 3
3 5 5
4 3 4
4 5 13
4 6 15
5 6 4
*/

我这里写的是优先队列优化的版本时间复杂度为O((m+n)logn),但这个算法存在一定的弊端,它无法解决带有负权边的问题,为什么了,假设有一个回路,权值之和为负数,那么我们反复走这个回路,花费可以趋近负无穷


3.Bellman-Ford(解决负权边单源最短路)(边是带方向的)

核心思路:
对所有的边进行n-1次松弛操作。Bellmam-Ford第k轮松弛操作其实是源点“最多经过k条边”到达其余各个顶点的最短路径。所以虽最多进行n-1次松弛操作。

基本步骤:
n-1次松弛中,反复遍历所有的边,来缩短起点到其他点的距离




优化:
在实际操作中,通常在未达到n-1轮松弛前就已经计算出了最短路,我们可以用check标记一下dis数组在某轮操作中是否发生了变化,如果没有变化,便跳出循环即可。

#include<cstdio>
#include<vector>
#include<iostream>
#define inf 0x3f3f3f
const int maxn=1005;
using namespace std;int dis[maxn];
int u[maxn],v[maxn],w[maxn];int main(){int n,m,check;while(scanf("%d%d",&n,&m),n,m){//存图 for(int i=1;i<=m;i++)scanf("%d%d%d",&u[i],&v[i],&w[i]);//初始化dis数组for(int i=1;i<=n;i++)dis[i]=inf;dis[1]=0;//进行n-1轮松弛 for(int k=1;k<=n-1;k++){check=0;//遍历每一条边for(int i=1;i<=m;i++){if(dis[v[i]]>dis[u[i]]+w[i]){dis[v[i]]=dis[u[i]]+w[i];check=1;                }}                 if(check==0) break;}for(int i=1;i<=n;i++)printf("%d ",dis[i]); printf("\n");/*//判断是否有负权回路 int flag=0;for(int i=1;i<=m;i++)if(dis[v[i]]>dis[u[i]]+w[i]) flag=1;if(flag==0) printf("no\n");else printf("yes\n");*/}return 0;
}
/*
5 5
2 3 2
1 2 -3
1 5 5
4 5 2
3 4 3
*/

(再次感谢学长学姐们的图)

最短路算法(Floyd,Dijkstra,.Bellman-Ford)相关推荐

  1. 算法小讲堂之最短路算法(Floyd+bellman+SPFA+Dijkstra)

    前言 如果你对图论相关知识一点也没有,那么建议您先去了解这些知识:https://acmer.blog.csdn.net/article/details/122310835,然后就可以快乐的学习最短路 ...

  2. 最短路模板 - Floyd / Dijkstra

    Floyd算法: 写得很好的博客:最短路径问题---Floyd算法详解 算法的特点: 弗洛伊德算法是解决任意两点间的最短路径的一种算法,可以正确处理有向图或无向图或负权(但不可存在负权回路)的最短路径 ...

  3. 【最短路算法】dijkstra,SPFA和folyd

    在了解本知识点之前,首先要了解图的建立,也就是邻接表和邻接矩阵. 邻接矩阵适用于稠密图 邻接表适用于稀疏图 目录 单源最短路问题 dijkstra算法 SPFA算法 folyd算法 最小生成树 拓扑排 ...

  4. 最短路算法----floyd算法

    目录 1:Floyd算法的介绍 2:Floyd算法的代码展现 3:Floyd算法举例 1:Floyd算法的介绍 Floyd算法是属于最短路算法的一种,它是用来求多源最短路径,换句话来说就是求任意两个点 ...

  5. 详解最短路算法模板(dijkstra+floyd+spfa)

    1.Floyd_Warshall算法 核心思路:d[i][j] = min{d[i][j], d[i][k] + d[k][j]} 从i到j有两种路径,经过k点或是不经过k点,所以我们枚举k即可求所有 ...

  6. 图的最短路算法(Dijkstra和Floyd-Warshall)

    一.单源最短路(Dijkstra算法) 基本思想 选定一个源点,按路径长度递增次序,逐步产生最短路径(贪心),直到此源点到其他各顶点的最短路径全部求出为止. 数据结构 带权有向图G=(V,E),V = ...

  7. 最短路算法floyd

    内容: 对n个点(n<=450),已知他们的边,也就是相邻关系,求任意两个点的最短距离. 代码: for(int k=1; k<=n; k++)//k写在外面for(int i=1; i& ...

  8. (最短路径算法整理)dijkstra、floyd、bellman-ford、spfa算法模板的整理与介绍

    这一篇博客以一些OJ上的题目为载体.整理一下最短路径算法.会陆续的更新... 一.多源最短路算法--floyd算法 floyd算法主要用于求随意两点间的最短路径.也成最短最短路径问题. 核心代码: / ...

  9. 最短路算法详解(Dijkstra/SPFA/Floyd)

    转自:http://blog.csdn.net/murmured/article/details/19281031 一.Dijkstra Dijkstra单源最短路算法,即计算从起点出发到每个点的最短 ...

  10. 最短路算法 :Bellman-ford算法 Dijkstra算法 floyd算法 SPFA算法 详解

     本文链接   :http://www.cnblogs.com/Yan-C/p/3916281.html . 在本文中因为邻接表在比赛中不如前向星好写,而且前向星效率并不低所以,本文的代码 存图只 ...

最新文章

  1. 2016设置方框的尺寸_四种模板脚手架分类、优缺点及参数设置对比
  2. 1024 致敬极客精神,我们有一个3天的秘境邀请!
  3. Linux arm9 设置中断向量表,STM32学习笔记之中断向量表,MDK程序启动分析
  4. Java线程详解(2)-创建与启动
  5. Gitee X Serverless Devs 邀你来“领赏”啦!
  6. NOIP模拟题——神秘大门
  7. matlab的词云,Word Cloud (词云) - JavaScript
  8. UML之一综合设计例题
  9. 在linux中怎么装python3环境,在Linux环境下安装Python3
  10. GitLab 严重漏洞可用于接管用户账户
  11. Spring Data JPA 必须掌握的 20+ 个查询关键字
  12. 【过拟合】再也不用担心过拟合的问题了
  13. Django报错:'Specifying a namespace in include() without providing an app_name '
  14. 论文文献综述的题目是什么样的,应该怎么写?
  15. mac安装正在计算机,出现“无法在计算机上安装macOS”错误时该怎么办?
  16. 计算机转换汉子英语,中英文切换(电脑怎么切换拼音打字)
  17. 电脑的视频太大,如何压缩视频
  18. 有经验JAVA程序员如何提升自己?
  19. web2.0带来的狂潮
  20. 开源的抖音壁纸即刻取图出现“这张图不见了,联系客服解决吧”的解决办法

热门文章

  1. python使用谷歌翻译
  2. 刘备比诸葛亮都强在什么地方
  3. java htmlunit js_Java版web浏览器htmlunit使用记录-js解释器
  4. mysql 如何查看建表语句
  5. 程序员福音:字节要上市了?
  6. 类加载机制:双亲委任模型和tomcat类加载器
  7. Java main方法_解释Java中的main方法,及其作用_一个java文件中可包含多个main方法
  8. 2023年高校“产教融合”新工科人工智能领域高质量创新人才培养研讨会暨创新创业学院、创新创业教育实践基地建设交流会成功
  9. 《习惯的力量》一书核心总结
  10. 计算机没考好的检讨书300百以上,【检讨书300字关于考试没考好】_关于考试没考好的检讨书怎么写300字急!!!急!!!急!!!...