Dijkstra算法 详细解释

Dijkstra算法适用于边权值为正的情况,如果边权值为负数就才用另一种最短路算法Bellman-Ford算法。

该算法是指从单个源点到各个结点的最短路,该算法适用于有向图和无向图。

复杂度O(n^2)

伪代码:

伪代码
清楚所有点的标号
全部d[i] = INF
然后将图信息权值复制到d中
循环n次{在所有为标号的结点中,选出d值最小的结点x给x标记对于从x出发的所有边(x,y),更新d[y] = min{d[y],d[y]+w(x,y)}
}

故而得到的代码模板:

void dijkstra(int u)
{memset(v,0,sizeof v);memset(dis,INF,sizeof dis);v[u] = 1;for(int i = 1; i <= n; i++)dis[i] = min(dis[i],Map[u][i]);for(int i = 1; i <= n; i++){int x,m = INF;for(int y = 1; y <= n; y++)if(!v[y] && dis[y] <= m)m = dis[x = y];v[x] = 1;for(int y = 1; y <= n; y++)dis[y] = min(dis[y],dis[x]+Map[x][y] );}
}

数据样例:

5 6 1
1 2 5
1 3 8
2 3 1
2 4 3
4 5 7
2 5 2

所描绘的图为:

下面模拟一下(来源 请进入):

我们以1为源点,来求所有点到一号点的最短路径。

先建立一个dis数组,dis[i]表示第i号点到源点(1号点)的估计值,你可能会问为什么是估计值,因为这个估计值会不断更新,更新到一定次数就变成答案了,这个我们一会再说。

然后我们在建立一个临界矩阵,叫做:map,map[i][j]=v表示从i到j这条边的权值是v。

dis初始值除了源点本身都是无穷大。源点本身都是0.

先从1号点开始。一号点,map[1][2]=5,一号点离2号点是5,比无穷大要小,所以dis[2]从无穷大变成了5。顺便,我们用minn记录距离1号点最短的点,留着以后会用。

dis[0,5,∞,∞,∞]。minn=2。

然后搜到3号点,map[1][3]=8,距离是8,比原来的dis[3]的∞小,于是dis[3]=8。但是8比dis[2]的5要大,所以minn不更新。

dis[0,5,8,∞,∞]

接着分别搜索4,5号点,发现map[1][4],map[1][5]都是∞,所以就不更新。

现在,dis数组所呈现的明显不是最终答案,因为我们才更新一遍,现在我们开始第二次更新,第二次更新以什么为开始呢?就是以上一次我们存下来的,minn,相当于把2当源点,求所有点到它的最短路,加上它到真正的源点(1号点)的距离,就是我们要求的最短路。

从2号点开始,搜索3号点,map[2][3]=1,原本dis[3]=8,发现dis[2]+map[2][3]=5+1=6<dis[3](8)所以更新dis[3]为6,minn=3

dis[0,5,6,∞,∞] minn=3.

然后搜索4号点,map[2][4]=3,原本dis[4]=∞,所以,dis[2]+map[2][4]=5+3=8<dis[4](∞)所以更新dis[4]=8,因为map[2][4]=3,3>1,minn不更新。

dis[0,5,6,8,∞] minn=3.

接着搜索5号点,map[2][5]=2,5+2=7,7<∞,dis[5]=7minn不变。

dis[0,5,6,8,7]

二号点搜完,因为minn是3,继续搜索3号点。

三号点还是按照二号点的方法搜索,发现没有可以更新的,然后搜索四号。

四号搜5号点,发现8+7>5+2,所以依然不更新,然后跳出循环。

现在的估计值就全部为确定值了:

dis[0,5,6,8,7]

这就是每个点到源点一号点的距离,我们来看一下代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 500;
const int INF = 0x3f3f3f3f;
int n,m,dis[maxn],Map[maxn][maxn],v[maxn];
void dijkstra(int u)
{memset(v,0,sizeof v);memset(dis,INF,sizeof dis);v[u] = 1;for(int i = 1; i <= n; i++)dis[i] = min(dis[i],Map[u][i]);for(int i = 1; i <= n; i++){int x,m = INF;for(int y = 1; y <= n; y++)if(!v[y] && dis[y] <= m)m = dis[x = y];v[x] = 1;for(int y = 1; y <= n; y++)dis[y] = min(dis[y],dis[x]+Map[x][y] );}
}
int main()
{int a,u,v,w;scanf("%d%d%d",&n,&m,&a);memset(Map, INF, sizeof Map);for(int i = 0; i < m; i++){scanf("%d%d%d",&u,&v,&w);Map[u][v] = w;Map[v][u] = w; //该图为无向图,若为有向图则需要少建立一个边信息}for(int i = 1; i <= n; i++)Map[i][i] = 0;dijkstra(a);for(int i = 1; i <= n; i++)cout<<dis[i]<<" ";return 0;
}

上述算法采用邻接矩阵来存储边的信息,此种方法的时间复杂度为O(n^2)。

在很多情况中,图中的边并没有那么多,mlog(n) 比 n^2 小的多。m 远小于 n^2的图称为稀疏图,而 m 相对较大的图为稠密图。

稀疏图适合使用vector数组来储存,还有一种表示方法便是——邻接表。

Dijkstra算法 详细讲解相关推荐

  1. 【转载】最短路径之Dijkstra算法详细讲解

    1  最短路径算法 在日常生活中,我们如果需要常常往返A地区和B地区之间,我们最希望知道的可能是从A地区到B地区间的众多路径中,那一条路径的路途最短.最短路径问题是图论研究中的一个经典算法问题, 旨在 ...

  2. dijkstra标号法表格_Dijkstra算法详细讲解

    最短路径之 Dijkstra 算法详细讲解 1 最短路径算法 在日常生活中,我们如果需要常常往返 A 地区和 B 地区之间,我们最希望 知道的可能是从 A 地区到 B 地区间的众多路径中,那一条路径的 ...

  3. lamport面包店算法详细讲解及代码实现

    lamport面包店算法详细讲解及代码实现 1 算法详解 1.1 一个较为直观的解释 1.2 Lamport算法的时间戳原理 1.3 Lamport算法的5个原则 1.4 一个小栗子 2 算法实现 3 ...

  4. Adaboost算法详细讲解

    转自线上数据建模 Adaboost算法详细讲解 Adaboost(Adaptive Boosting): Adaboost是Boosting模型,和bagging模型(随机森林)不同的是:Adaboo ...

  5. 模拟退火算法详细讲解(含实例python代码)

    模拟退火算法详细讲解(含实例python代码) (一)模拟退火算法简介 (二)模拟退火算法原理 (三)退火过程中参数控制 (四)算法步骤 (五)实例分析 最近老师要求做模拟退火算法实验,看了很多博客之 ...

  6. C语言老鼠走迷宫(单路径)算法详细讲解

    最近在学习C语言的一些经典算法,其中遇到了一点困难,导致卡进度了.琢磨了很久,在绘制流程图时,突然灵感大开理解了,老鼠走迷宫算法的奇妙.所以写了这个,一来是方便以后右和我类似的同学自学时,遇到这个问题 ...

  7. 排序算法详细讲解(超酷)

    目录 前言 一.插入类排序 1.直接插入排序 2.折半插入排序 3.希尔排序 二.交换类排序 1.冒泡排序(相邻比序法) 2.快速排序 三.选择类排序 1.简单选择排序 2.树形选择排序 3.堆排序 ...

  8. KMP算法详细讲解(看完不会请打我)

    文章目录 前言 一:情景导入-如何快速在一个主串找到目标字符串 二:详解KMP (1)暴力匹配的缺点 (2)最长相同前缀和后缀 (3)究竟怎么回溯 (3)next数组 (4)求解next数组 A:ne ...

  9. 迪杰斯特拉(Dijkstra)(详细讲解+Java源码)

    迪杰斯特拉算法兼具动态规划和贪心思想 贪心思想 例:A能到达的各点中,AC距离最小 那么无论后续怎么变化,再找任何其他路径,A到C的距离都不可能小于A->x->C,因为A->x的距离 ...

最新文章

  1. springboot(十八):使用Spring Boot集成FastDFS
  2. gitlab新增ssh
  3. 放授权代码的php文件夹,自己的项目如果包含别人的开源代码,licence文件应放在哪里...
  4. 利用FastJSON 把list和map转换成Json
  5. python字符串截取_Python-变量-No3
  6. 液冷计算机组装,电脑水冷散热器原理解密及安装方法
  7. guzz 1.3.0大版本发布,支持Spring事务
  8. 怎么下载php文件的电影,下电影下下来是.php格式,请问怎么打开?
  9. HashMap底层实现原理
  10. Android8.1 APK安装过程源码解析
  11. java 手机动态口令_动态密码TOTP的Java实现
  12. 使用C# .net开发微信公众号之服务器URL配置
  13. 基于tesseract_ocr实现图片中汉字辨识
  14. 【树莓派不吃灰】基础篇⑮ SSH远程访问安全,涉及/etc/hosts.allow白名单 和 /etc/hosts.deny黑名单、ufw防火墙、密钥登录
  15. 2019-CS224N-Assignment 1: Exploring Word Vectors
  16. NodeJS:redis 入门级使用示例 hgetall
  17. 【Java开发者专场】阿里专家梁笑:2018双十一下单成功率99.9%!供应链服务平台如何迎接大促...
  18. FPGA — Overview
  19. 计算机网络入门之TCP/IP模型
  20. Ubuntu 22.04(LinuxMint 21)编译wine7.19安装最新微信3.7.6及QQ体会

热门文章

  1. QQ秀已然式微,而同时迭代的厘米秀正在雄起。
  2. 今天没有穿内裤._今天...
  3. 个人用微信,支付宝在网站收款实现
  4. InnoDB-聚簇索引和MyISAM非聚簇索引
  5. Poser 11基本使用
  6. 4.1内网穿透-holer,实现外网访问地址,此处用于webhook地址
  7. jquery对文本赋值和取值_jQuery常用的取值或赋值的方法
  8. 法官批准离婚申请 布兰妮正式恢复“单身”(图)
  9. 一、MySQL数据库设置默认时区
  10. short与Short类型转换其它数据类型