Dijkstra(迪杰斯特拉)单源最短路径算法

Dijkstra思想

Dijkstra是一种求单源最短路径的算法。

Dijkstra仅仅适用于非负权图,但是时间复杂度十分优秀。

Dijkstra算法主要思想是:

主要思想是,将结点分成两个集合:已确定最短路长度的,未确定的。

一开始第一个集合里只有节点V。

然后重复这些操作:

1.对那些刚刚被加入第一个集合的结点的所有出边执行松弛操作。

2.从第二个集合中,选取一个最短路长度最小的结点,移到第一个集合中。

用暴力算法的时间复杂度是Ο(n2+m) = Ο(n2)。

用小根堆优化的时间复杂度是Ο(m log n)。

还有一些复杂的实现Dijkstra算法,比如说:priority_queue(时间复杂度:Ο(m log m))

                    ZKW线段树(时间复杂度:O(m log n + n) = Ο(m log n))

                    fibonacci堆(时间复杂度:Ο(n log n + m))

感兴趣的OIer想具体了解这几种方法,可以上网查一查,这里不多赘述。

Dijkstra暴力法例题

Dijkstra小根堆优化例题

Dijkstra暴力法代码

// by kyrence
#include <bits/stdc++.h>
using namespace std; const int S = 3e3 + , INF = 0x3f3f3f3f;
int adj[S][S], dist[S], n, m;
bool vis[S]; void dijkstra() {
memset(dist, INF, sizeof(dist));
memset(vis, , sizeof(vis));
dist[] = ;
for (int i = ; i < n; i++) {
int x = ;
for (int j = ; j <= n; j++) //找到未标记的节点中dist最小的节点对其它节点进行更新
if (!vis[j] && (!x || dist[j] < dist[x]))
x = j;
vis[x] = ;
for (int j = ; j <= n; j++) //更新其它节点的最短路
dist[j] = min(dist[j], dist[x] + adj[x][j]);
}
} int main() {
memset(adj, INF, sizeof(adj)); //构建邻接矩阵
scanf("%d%d", &n, &m);
for (int i = ; i <= n; i++) adj[i][i] = ; //节点V到节点V的距离为0
for (int i = ; i <= m; i++) {
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
adj[x][y] = z; //有向图
//adj[x][y] = adj[y][x] = z; 无向图
}
dijkstra(); //dijkstra暴力法求解单源最短路径
for (int i = ; i <= n; i++)
printf("%d\n", (dist[i] == INF ? - : dist[i])); //-1代表节点1到节点i没有路径
return ;
}

Dijkstra小根堆优化代码

// by kyrence
#include <bits/stdc++.h>
using namespace std; const int N = 1e5 + , M = 1e6 + , INF = 0x3f3f3f3f;
int head[N], ver[M], edge[M], Next[M], dist[N]; //构建邻接表
int n, m, tot;
bool vis[N];
priority_queue<pair<int, int> > q; //小根堆第一项取负,使小根堆变成大根堆
//在不使用小顶优先队列情况下取负将小根堆变成大根堆加速优先队列,常见的加速技巧 void add(int x, int y, int data) { //邻接表存储图
ver[++tot] = y;
edge[tot] = data;
Next[tot] = head[x];
head[x] = tot;
} void dijkstra() {
memset(dist, INF, sizeof(dist));
memset(vis, , sizeof(vis));
dist[] = ; q.push(make_pair(, ));
while (!q.empty()) {
int u = q.top().second; q.pop(); //找到未访问节点中dist最小的节点
if (vis[u]) continue; //如果节点u已经访问则忽略
vis[u] = ;
for (int i = head[u]; i; i = Next[i]) { //邻接表访问出边
int y = ver[i], z = edge[i];
if (dist[y] > dist[u] + z) {
dist[y] = dist[u] + z; //更新节点
q.push(make_pair(-dist[y], y)); //取负值,加速小根堆
}
}
}
} int main() {
scanf("%d%d", &n, &m);
for (int i = ; i <= m; i++) {
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
add(x, y, z); //无向图
//add(x, y, z); add(y, x, z); 有向图
}
dijkstra(); //dijkstra小根堆优化求解单源最短路径
for (int i = ; i <= n; i++)
printf("%d\n", (dist[i] == INF ? - : dist[i])); //-1代表节点1到节点i没有路径
return ;
}

力荐使用小根堆优化,代码简洁直观易懂,空间小,时间复杂度优。

Dijkstra求解单源最短路径的更多相关文章

  1. Dijkstra算法——单源最短路径问题

    学习一个点到其余各个顶点的最短路径--单源最短路径 Dijkstra算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有向 ...

  2. 单源最短路径——dijkstra算法

    dijkstra算法与prim算法的区别   1.先说说prim算法的思想: 众所周知,prim算法是一个最小生成树算法,它运用的是贪心原理(在这里不再证明),设置两个点集合,一个集合为要求的生成树的 ...

  3. [C++]单源最短路径:迪杰斯特拉(Dijkstra)算法(贪心算法)

    1 Dijkstra算法 1.1 算法基本信息 解决问题/提出背景 单源最短路径(在带权有向图中,求从某顶点到其余各顶点的最短路径) 算法思想 贪心算法 按路径长度递增的次序,依次产生最短路径的算法 ...

  4. 【转】Dijkstra算法(单源最短路径)

    原文:http://www.cnblogs.com/dolphin0520/archive/2011/08/26/2155202.html 单源最短路径问题,即在图中求出给定顶点到其它任一顶点的最短路 ...

  5. 单源最短路径Dijkstra算法,多源最短路径Floyd算法

    1.单源最短路径 (1)无权图的单源最短路径 /*无权单源最短路径*/ void UnWeighted(LGraph Graph, Vertex S) { std::queue<Vertex&g ...

  6. 单源最短路径算法:迪杰斯特拉 (Dijkstra) 算法(二)

    一.基于邻接表的Dijkstra算法 如前一篇文章所述,在 Dijkstra 的算法中,维护了两组,一组包含已经包含在最短路径树中的顶点列表,另一组包含尚未包含的顶点.使用邻接表表示,可以使用 BFS ...

  7. 单源最短路径算法:迪杰斯特拉 (Dijkstra) 算法(一)

    一.算法介绍 迪杰斯特拉算法(英语:Dijkstra's algorithm)由荷兰计算机科学家艾兹赫尔·迪杰斯特拉在1956年提出.迪杰斯特拉算法使用了广度优先搜索解决赋权有向图的单源最短路径问题. ...

  8. SPFA解决单源最短路径

    SPFA(Shortest Path Faster Algorithm): 一:基本算法 在求解单源最短路径的时候,最经典的是 Dijkstra 算法,但是这个算法对于含有负权的图就无能为力了,而 B ...

  9. JAVA之单源最短路径(Single Source Shortest Path,SSSP问题)dijkstra算法求解

    题目简介:给定一个带权有向图,再给定图中一个顶点(源点),求该点到其他所有点的最短距离,称为单源最短路径问题. 如下图,求点1到其他各点的最短距离 准备工作:以下为该题所需要用到的数据 int N; ...

随机推荐

  1. 【u107】数字游戏(bds)

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 有这么一个游戏: 写出一个1-N的排列a[i],然后每次将相邻两个数相加,构成新的序列,再对新序列进行 ...

  2. vue的filters过滤器的使用

    举个例子,过滤后台转过来的时间格式2019-08-29T02:15:08.000+0000转换为2019-08-29T02:15:08 html部分 <span v-if="item. ...

  3. Shave Beaver! CodeForces - 331B2 (线段树)

    题面 The Smart Beaver has recently designed and built an innovative nanotechnologic all-purpose beaver ...

  4. selenium docs

    Note to the Reader - Docs Being Revised for Selenium 2.0! Introduction Test Automation for Web Appli ...

  5. 大数据hadoop集群部署(一)

     环境系统配置  JAVA虚拟机的安装

  6. 【题解】BZOJ4241: 历史研究(魔改莫队)

    [题解]BZOJ4241: 历史研究(魔改莫队) 真的是好题啊 题意 给你一个序列和很多组询问(可以离线),问你这个区间中\(\max\){元素出现个数\(\times\)元素权值} IOI国历史研究 ...

  7. 洛谷$P3308\ [SDOI2014]LIS$ 网络流

    正解:网络流 解题报告: 传送门$QwQ$ 恩先不考虑关于那个附加属性的限制,考虑这题怎么做? 首先这题从名字开始就让人忍不住联想起网络流24题里的那个最长不下降子序列?于是同样考虑预处理一个$f$呗 ...

  8. 基于 HTML5 WebGL 与 WebVR 3D 虚实现实的可视化培训系统

    前言 2019 年 VR, AR, XR, 5G, 工业互联网等名词频繁出现在我们的视野中,信息的分享与虚实的结合已经成为大势所趋,5G 是新一代信息通信技术升级的重要方向,工业互联网是制造业转型升级 ...

  9. CentOS8安装fastdfs6.06

    目录 一.准备环境 二.解压并编译安装 1.解压下载好的包 2.编译安装 2.1.编译安装 libfastcommon 2.2.编译安装 fastdfs 2.3.安装 nginx 和 fastdfs- ...

  10. 《算法笔记》之基础C/C++进阶

    这一次主要讲C++不同于C的地方:类. 1.类的定义 定义一个类,本质上是定义一个数据类型的蓝图.这实际上并没有定义任何数据,但它定义了类的名称意味着什么,也就是说,它定义了类的对象包括了什么,以及可 ...