什么是最短路径问题?

简单来讲,就是用于计算一个节点到其他所有节点的最短路径。

单源最短路算法:已知起点,求到达其他点的最短路径。

常用算法:Dijkstra算法、Bellman-ford算法、SPFA算法

多源最短路算法:求任意两点之间的最短路径。

常用算法:floyd算法

单源最短路径——Dijkstra

Dijkstra算法是经典的最短路径算法,用于计算一个节点到其他所有节点的最短路径。

主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。

时间复杂度:O(n^2)

处理问题:单源、无负权、有向图、无向图最短路径

不能使用的情况:边中含有负权值(无法判断)

#define INF 0x3f3f3f3fint e[Max][Max];//e[i][j]代表从i->j的距离,不通设为无穷大
int dis[Max];//dis[i]代表从起点到i的最短距离
bool book[Max];//book[i]代表点i是否在S中
int n;//n个顶点
int s;//起点void Dijkstra()
{for(int i=1;i<=n;i++)//初始化dis数组dis[i]=e[s][i];for(int i=1;i<=n;i++)//初始化book数组book[i]=0;dis[s]=0;book[s]=1;for(int i=1;i<=n-1;i++)//Dijkstra算法核心语句
    {int minDis=INF;int k;//找到与s最近的顶点kfor(int j=1;j<=n;j++){if(book[j]==0 && dis[j]<minDis){minDis=dis[j];k=j;}}book[k]=1;for(int j=1;j<=n;j++)//“松弛”过程
        {if(e[k][j]<INF){if(dis[j]>dis[k]+e[k][j])dis[j]=dis[k]+e[k][j];}}}
}

基本思想:把带权图中所有的点分为两部分S∪U,S为已经求出从起点到该点的最短路径的点集合,U中为未确定最短路径的点集合。把U中的点一个一个加入到S中,最后求出全部最短路径。

如何把U中的点加入S中呢?

①初始时,S只包含源点s,即S={s},dis[s]=0。U包含除v外的其他顶点,即U={其余顶点},若s与U中顶点u有边,则dis[u]=e[s][u],否则,dis[u]=∞。

②从U中找到一个与源点s距离最小(min(dis[]))的顶点k,把k加入S中,dis[k]确定(仔细想想,s与k最短路径必定是dis[k]=e[s][k],找不到更短的)。

③以k为新考虑的中间点,修改源点s到U中各顶点的距离dis[]:若从源点s到顶点u的距离(dis[k]+e[k][u],经过顶点k)比原来距离(dis[u],不经过顶点k)短,则修改顶点u的距离值,修改后的距离值的顶点k的距离加上边上的权。(这一过程称为“松弛”)

④重复步骤②和③直到所有顶点都包含在S中。

算法优化:这里面每次都要寻找距离最短的那个点和距离,时间复杂度为O(n),可以用“堆”来优化,是时间复杂度降为O(lgn)。

算法过程详解:http://ahalei.blog.51cto.com/4767671/1387799

单源最短路径——Bellman-ford算法

求单源最短路径,可以判断有无负权回路(若有,则不存在最短路), 时效性较好,时间复杂度O(VE)。

处理问题:单源、可有负权、有向图、无向图最短路径

注:下面代码为有向图最短路径

#define INF 0x3f3f3f3fstruct Edge{int u;//起int v;//终int weight;//长度
};Edge edge[maxm];//用来存储所有的边
int dis[maxn];//dis[i]表示源点到i的最短距离
int n,m;//n个点,m条边
int s;//源点bool Bellmen_ford()
{for(int i=1;i<=n;i++)//初始化dis[i]=INF;dis[s]=0;//源节点到自己的距离为0for(int i=1;i<n;i++)//松弛过程,计算最短路径
    {for(int j=1;j<=m;j++){if(dis[edge[j].v]>dis[edge[j].u]+edge[j].weight)//比较s->v与s->u->v大小dis[edge[j].v]=dis[edge[j].u]+edge[j].weight;}}for(int j=1;j<=m;j++)//判断是否有负边权的边
    {if(dis[edge[j].v]>dis[edge[j].u]+edge[j].weight)return false;}return true;
}

基本思想:bellman-ford的思想和dijkstra很像,其关键点都在于不断地对边进行松弛。而最大的区别就在于前者能作用于负边权的情况。其实现思路是在求出最短路径后,判断此刻是否还能对便进行松弛,如果还能进行松弛,便说明还有负边权的边。

单源最短路径——SPFA算法

上一种算法其实不好用,复杂度太高,SPFA算法是Bellman-ford算法的队列优化,比较常用。SPFA算法在负边权图上可以完全取代Bellman-ford算法,另外在稀疏图中也表现良好。但是在非负边权图中,为了避免最坏情况的出现,通常使用效率更加稳定的Dijkstra算法,以及它的使用堆优化的版本。通常的SPFA算法在一类网格图中的表现不尽如人意。不是很稳定,不如Dijkstra。

处理问题:单源、可有负权、有向图、无向图最短路径(自身其实无法处理负权)

#define INF 0x3f3f3f3fint dis[MAX];//dis[i]表示起点到i的最短距离
bool vis[MAX];//是否访问过点i
int e[MAX][MAX];//矩阵int n,m;//点和边的数量
int s;//源点void SPFA()
{for(int i=1;i<=n;i++)//初始化
    {dis[i]=INF;vis[i]=false;}queue<int> q;q.push(s);dis[s]=0;vis[s]=true;while(!q.empty()){int cur=q.front();q.pop();vis[cur]=false;for(int i=1;i<=n;i++){if(e[cur][i]!=INF&&dis[i]>=dis[cur]+e[cur][i]){dis[i]=dis[cur]+e[cur][i];if(!vis[i]){vis[i]=true;q.push(i);}}}}
}

算法思想:

设立一个队列用来保存待优化的点,优化时每次取出队首结点u,并且用u点当前的最短路径估计值对u点所指向的结点v进行松弛操作,如果v点的最短路径估计值有所调整,且v点不在当前的队列中,就将v点放入队尾。这样不断从队列中取出结点来进行松弛操作,直至队列空为止。

算法过程详解:http://www.360doc.com/content/13/1208/22/14357424_335569176.shtml

例题:http://ac.jobdu.com/problem.php?pid=1008

多源最短路径——Floyd算法

Floyd算法是一种利用动态规划思想的计算加权图中多源点之间最短路径的算法。可以正确处理有向图或负权的最短路径问题。

时间复杂度:O(N^3)

空间复杂度:O(N^2)

处理问题:多源、可有负权、有向图、无向图最短路径

int e[Max][Max];//e[i][j]代表从i->j的距离,不通设为无穷大
int n;//n个顶点
//Floyd算法
void Floyd()
{for(int k=1;k<=n;k++)//遍历所有的中间点{for(int i=1;i<=n;i++)//遍历所有的起点{for(int j=1;j<=n;j++)//遍历所有的终点{if (e[i][j]>e[i][k]+e[k][j])//如果当前i->j的距离大于i->k->j的距离之和e[i][j]=e[i][k]+e[k][j];//更新从i->j的最短路径}}}
}

算法思想:

①如果不允许有中转点,那么最短路径就是我们的e[][]原始矩阵;

②现在只允许经过1号顶点进行中转,判断e[i][1]+e[1][j]是否比e[i][j]要小,修改e[][];

③接下来只允许经过1和2号顶点进行中转……

④最后,允许经过1~n号所有顶点进行中转,得到最后的e[][],就是要求的任意两点之间的最短路程。

这里面是动态规划思想的体现。状态转移方程:e[i,j]=max{e[i,k]+e[k,j],e[i,j]};

算法过程:对于每一对顶点 i 和 j,看看是否存在一个顶点 k 使得从 i 到 k 再到 j 比已知的路径更短。如果是,则更新它。

算法过程详解:http://ahalei.blog.51cto.com/4767671/1383613

另外,特别鸣谢,本文参考(含大量例题):http://blog.csdn.net/hjd_love_zzt/article/details/26739593

作者: AlvinZH

出处: http://www.cnblogs.com/AlvinZH/

本人Github:https://github.com/Pacsiy/JobDu

本文版权归作者AlvinZH和博客园所有,欢迎转载和商用,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.

转载于:https://www.cnblogs.com/AlvinZH/p/6789912.html

四大算法解决最短路径问题(Dijkstra+Bellman-ford+SPFA+Floyd)相关推荐

  1. 图论算法之最短路径(Dijkstra、Floyd、Bellman-ford和SPFA)

    图论算法之最短路径(Dijkstra.Floyd.Bellman-ford和SPFA) 1.图论最短路径概述 图论算法为了求解一个顶点到另一个顶点的最短路径,即如果从图中某一顶点(称为源点)到达另一顶 ...

  2. 图论算法(二)-最短路径的Dijkstra [ 单源 ] 和Floyd[ 多源 ] 解法(JAVA )

    一.Dijkstra算法 问题描述:求一个点到任意个点的距离 思路:单源最短路径问题,使用Dijkstra算法 Input: 6 9 1 2 1 1 3 12 2 3 9 2 4 3 3 5 5 4 ...

  3. 【图论算法】最短路径算法(无权最短路径、Dijkstra算法、带负边值的图、无圈图)

    本篇博客将考察各种最短路径问题.     无权最短路径     Dijkstra 算法     具有负边值的图     无圈图     所有顶点对间的最短路径     最短路径的例子–词梯游戏 输入是 ...

  4. 【恋上数据结构】图代码实现、最小生成树(Prim、Kruskal)、最短路径(Dijkstra、Bellman-Ford、Floyd)

    图 最小生成树(Minimum Spanning Tree) Prim算法 切分定理 Prim算法 – 执行过程 Prim算法 – 代码实现 Kruskal算法 Kruskal算法 – 执行过程 Kr ...

  5. 解决最短路径的Dijkstra算法详解,附加Java代码

    1. 最短路径问题 最短路径问题是生活中经常碰到的一类问题,如机器人路径规划,数学竞赛以及真实的工程施工问题:甚至是我们程序员笔试必刷算法题.其实问题很简单,就是有很多个节点,我们要计算出一个初始点到 ...

  6. 迪杰斯特拉(Dijkstra)算法解决最短路径问题

    Dijkstra 算法介绍 迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959年提出的,因此又叫狄克斯特拉算法.迪杰斯特拉(Dijkstra)算法是最经典的最短路径算法之一,用 ...

  7. dijkstra 算法_最短路径问题Dijkstra算法详解

    1.Dijkstra算法介绍 · 算法起源: · Djkstra 算法是一种用于计算带权有向图中单源最短路径(SSSP:Single-Source Shortest Path)的算法,由计算机科学家E ...

  8. 最短路[Dijkstra和堆优化的Dijkstra][Bellman-Ford和SPFA][Floyd最短路](更新中)

    文章目录 第一类:单源最短路 一 所有边权都是正数(Dijkstra) 朴素版Dijkstra(稠密图) 堆优化版Dijkstra(稀疏图) 二 存在负权边(BF和SPFA) 第二类:多源汇最短路(F ...

  9. python贪心算法最短路径_dijkstra算法(贪心算法)——解决最短路径问题

    最短路径 给定一张带权图和其中的一个点(作为源点),求源点到其余顶点的最短路径 基本思想 1)源点u,所有顶点的集合V,集合S(S中存有的顶点,他们到源点的最短路径已经确定,源点u默认在S中),集合V ...

最新文章

  1. 300万知乎多标签文本分类任务经验分享(附源码)
  2. vue动态绑定类样式ClassName知多少
  3. 9600kf功耗和温度评测_谁更受主流消费者青睐:AMD锐龙5 3500X对比英特尔酷睿i5-9600KF...
  4. Objective-C ---JSON 解析 和 KVC
  5. PHP操作tcpdf插件生成PDF
  6. 跨域问题:Access-Control-Allow-Origin
  7. Android Studio 利用系统签名打包apk
  8. android计步器报告书,Android精准计步器开发-Dylan计歩
  9. PINN内嵌物理知识神经网络入门及文献总结
  10. JDK下载 JVM调优工具jvisualvm下载
  11. 《ERP原理》期末复习——第一章 初识ERP(企业资源计划)
  12. 计算机四级网络工程师知识点(非常全面)
  13. 由程序猿yyyy-MM-dd跨年Bug引发的深思
  14. 张学孟 (帮别人名字作诗)
  15. Approaching ANXIETY DISORDER
  16. Css3实现背景毛玻璃效果
  17. wifi连接一段时间才能上网_Win7系统下连接wifi一段时间就自动断线怎么办【图文】...
  18. 机器人图形变变变_幼儿园全景数学特色课程
  19. 腾讯云学生机官网地址在哪里?
  20. 从实战经验来看 究竟如何才能做出赚钱的量化投资策略?

热门文章

  1. Flutter入门三部曲(3) - 数据传递/状态管理 | 掘金技术征文
  2. 三个值得期待的JavaScript新功能!
  3. 十四周三次课、MySQL主从配置
  4. Mongoose快速入门
  5. VIM使用系列:寄存器与复制粘贴缓冲区
  6. 40个非常有创意的404页面设计作品
  7. Android 退出应用程序
  8. 结构型模式—享元模式
  9. 2019牛客暑期多校训练营(第八场)G Gemstones(模拟)
  10. cmd copy命令 文件复制【转】