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; ...
随机推荐
- 51nod 1307绳子和重物
1307 绳子与重物 题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 收藏 关注 有N条绳子编号 0 至 N - 1,每条绳子后 ...
- H3C使用tracert命令--用户视图
<H3C>tracert ? -a 指明 ...
- vue的filters过滤器的使用
举个例子,过滤后台转过来的时间格式2019-08-29T02:15:08.000+0000转换为2019-08-29T02:15:08 html部分 <span v-if="item. ...
- indexdb开cai发keng实zhi践lu
一直在维护一个用html2canvas截图转base64保存的项目,先不说html2canvas不同版本的不同坑的问题,就说转出来的这个base64字符长度实在太大了,尤其是遇到设计出图高度达到3千多 ...
- There is already an open DataReader associated with this Connection which must be closed first EF
废话不多说,直接 上图,及解决办法.不过问题还不是太清楚到底为什么会出现这个情况..........
- (转载)window安装mysql
一.MYSQL的安装 1.打开下载的mysql安装文件mysql-5.5.27-win32.zip,双击解压缩,运行“setup.exe”. 2.选择安装类型,有“Typical(默认)”.“Comp ...
- Keras lstm 文本分类示例
#基于IMDB数据集的简单文本分类任务 #一层embedding层+一层lstm层+一层全连接层 #基于Keras 2.1.1 Tensorflow 1.4.0 代码: '''Trains an LS ...
- git之github下载篇(ssh需要配置密钥)
1.使用git命令行下载 在想要下载的文件夹打开命令行 git clone ssh 成功如图所示 2.使用小乌龟图形界面克隆 在文件夹右键鼠标 如果复制有链接,会自动填入.点击确定 成功后如图
- 13.python基础试题(二)
借鉴:https://www.cnblogs.com/shengyang17/p/8543712.html https://www.cnblogs.com/you-wei1/p/9693254.htm ...
- 缓存, 队列(Redis,RabbitMQ)
Redis Redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorte ...