Dijkstra求解单源最短路径
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暴力法代码
// 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求解单源最短路径的更多相关文章
- Dijkstra算法——单源最短路径问题
学习一个点到其余各个顶点的最短路径--单源最短路径 Dijkstra算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有向 ...
- 单源最短路径——dijkstra算法
dijkstra算法与prim算法的区别 1.先说说prim算法的思想: 众所周知,prim算法是一个最小生成树算法,它运用的是贪心原理(在这里不再证明),设置两个点集合,一个集合为要求的生成树的 ...
- [C++]单源最短路径:迪杰斯特拉(Dijkstra)算法(贪心算法)
1 Dijkstra算法 1.1 算法基本信息 解决问题/提出背景 单源最短路径(在带权有向图中,求从某顶点到其余各顶点的最短路径) 算法思想 贪心算法 按路径长度递增的次序,依次产生最短路径的算法 ...
- 【转】Dijkstra算法(单源最短路径)
原文:http://www.cnblogs.com/dolphin0520/archive/2011/08/26/2155202.html 单源最短路径问题,即在图中求出给定顶点到其它任一顶点的最短路 ...
- 单源最短路径Dijkstra算法,多源最短路径Floyd算法
1.单源最短路径 (1)无权图的单源最短路径 /*无权单源最短路径*/ void UnWeighted(LGraph Graph, Vertex S) { std::queue<Vertex&g ...
- 单源最短路径算法:迪杰斯特拉 (Dijkstra) 算法(二)
一.基于邻接表的Dijkstra算法 如前一篇文章所述,在 Dijkstra 的算法中,维护了两组,一组包含已经包含在最短路径树中的顶点列表,另一组包含尚未包含的顶点.使用邻接表表示,可以使用 BFS ...
- 单源最短路径算法:迪杰斯特拉 (Dijkstra) 算法(一)
一.算法介绍 迪杰斯特拉算法(英语:Dijkstra's algorithm)由荷兰计算机科学家艾兹赫尔·迪杰斯特拉在1956年提出.迪杰斯特拉算法使用了广度优先搜索解决赋权有向图的单源最短路径问题. ...
- SPFA解决单源最短路径
SPFA(Shortest Path Faster Algorithm): 一:基本算法 在求解单源最短路径的时候,最经典的是 Dijkstra 算法,但是这个算法对于含有负权的图就无能为力了,而 B ...
- JAVA之单源最短路径(Single Source Shortest Path,SSSP问题)dijkstra算法求解
题目简介:给定一个带权有向图,再给定图中一个顶点(源点),求该点到其他所有点的最短距离,称为单源最短路径问题. 如下图,求点1到其他各点的最短距离 准备工作:以下为该题所需要用到的数据 int N; ...
随机推荐
- java反射小实例
利用反射实现 对配置文件的更改达到更改方法的目的 文件夹目录 首先Student类中有个sleep方法 pro.properties定义了参数 最后是RelectTestMain. package c ...
- springboot中redis做缓存时的配置
import com.google.common.collect.ImmutableMap;import org.slf4j.Logger;import org.slf4j.LoggerFactory ...
- CountDownLatch 部分加载和同时并发业务。
按顺序部分加载: import java.util.concurrent.CountDownLatch; /** * @Title: ThreadCountDownTest.java * @Descr ...
- ES6类的继承
ES6 引入了关键字class来定义一个类,constructor是构造方法,this代表实例对象. constructor相当于python的init 而this 则相当于self 类之间通过ext ...
- ELK系统分析nginx日志
一.nginx nginx 服务器日志的log_format格式: log_format main '$remote_addr - $remote_user [$time_local] "$ ...
- 关于hibernate5的映射文件和配置文件改变(转)
转自:https://blog.csdn.net/m0_37840000/article/details/78823716 配置文件: <!DOCTYPE hibernate-configura ...
- IDEA比较实用的插件之翻译插件(Translation)
插件名称:Translation 安装步骤:Mac 2019.2的IDEA安装步骤如下 InteIIij IDEA --> Preference --> Other Setting --& ...
- hadoop fs、hadoop dfs与hdfs dfs命令的区别
Hadoop fs:使用面最广,可以操作任何文件系统. hadoop dfs与hdfs dfs:只能操作HDFS文件系统相关(包括与Local FS间的操作),前者已经Deprecated,一般使用后 ...
- 超简单!pytorch入门教程(一):Tensor
http://www.jianshu.com/p/5ae644748f21 二.pytorch的基石--Tensor张量 其实标量,向量,矩阵它们三个也是张量,标量是零维的张量,向量是一维的张量,矩阵 ...
- 别怕,"卷积"其实很简单(下)
文章来自我的CSDN同名博客,欢迎文末扫码关注~ 定义 基于上一篇文章的通俗化例子,我们从基本概念上了解了卷积,那么更严格的定义是怎样的呢? 从数学上讲,卷积只不过是一种运算,对于很多没有 ...