dijkstra算法之优先队列优化
1.题目

分析与解题思路
dijkstra算法是典型的用来解决单源最短路径的算法,该算法采用贪心的思想,广度优先搜索的策略,每一轮从当前节点找对与其邻接的所有节点进行放松操作(比较距离源点的距离,来决定是否执行),记录当前节点为已访问,之后从所有未访问过的节点中找到距离源点最近的节点作为当前节点,重复上述操作。BFS策略体现在每次从当前节点,访问所有与其邻接的节点;贪心的思想体现在,每一轮之后,当前距离最短的点S被认为不存在从源点到S更短的路径,每次当通过S对与其邻接的节点进行放松后,可以将S从集合剔除,因为通过后续的到达S节点的距离一定更长。
证明:
假设源点为S0,当前节点为S,节点S0到节点u的距离为dis[u];
因为当前节点为S,说明其他节点u!=S,必有dis[u]>dis[S]
假如后续的节点v有一条到S的路径,源点到v的距离必然是通过S或者u进行放松的
dis[v]>=min{dis[u],dis[S]}
另外dijkstra算法只能解决权值为正的情况,当存在负权值时,算法可能出错,比如:
节点从1开始,根据贪心思想,下一下节点应该选择3,记录dis[3]=2
但是有更短的路径1->2->3 距离为1
测试用例

(测试用例1)

(测试用例2)
输入说明:
第一行:测试用例的数目
对于每一个测试用例,第一行,n,m,s;n代码节点的个数,m代表边的条数,s代码源节点
后面m行,u,v,w代表一条u->v权值为w的边
程序实现
public List<int[]>dijkstra1(int s);使用的是课本上比较朴素的实现方法。
下面是我自己的实现方法:
//采用优先队列优化
public List<int[]>dijkstra2(int s){
int[]path=new int[n+1];
int[]dis=new int[n+1];
boolean[]mark=new boolean[n+1];
Arrays.fill(dis, INF);
dis[s]=0;
path[s]=0;
PriorityQueue pq=new PriorityQueue(n);
for(int i=1;i<n;++i) {
for(Node temp:table.get(s)) {
if(!mark[temp.index]&&dis[s]+temp.weight<dis[temp.index]) {
if(dis[temp.index]==INF) {
dis[temp.index]=dis[s]+temp.weight;
pq.offer(temp.index, dis[temp.index]);
}else {
pq.increase(temp.index, dis[s]+temp.weight-dis[temp.index]);
dis[temp.index]=dis[s]+temp.weight;
}
path[temp.index]=s;
}
}
mark[s]=true;
s=pq.poll();
}
ArrayList<int[]>res=new ArrayList<int[]>(2);
res.add(path);
res.add(dis);
return res;
}
使用优先队列优化,每次寻找最小的距离的节点的时候就不用线性遍历整个表,可以在logV的时间复杂度内获得最小距离的节点;同时我在使用优先队列的时候,我的实现方式对优先队列有以下额外要求:(优先队列的代码有点长,具体情况源代码)
1) 能够更新元素
先找到指定的元素,根据2)中的方法,然后更新dis,如果dis变小进行上滤,dis变大进行下滤。
2) 能够在常数时间内找到在图中某个标号的节点在优先队列中的位置
一个很常见的思路就是使用空间换时间,使用一个数组保存Node在优先队列中的位置,并且在优先队列进行插入,删除,更新时也要同步更新。
运行截图

结论
朴素的实现时间复杂度是O(E*V)(我使用的是邻接表存储图),使用优先队列优化时间复杂度为O(VlogV);关于图的存储,稀疏图使用邻接表占用内存比较少,稠密图适合用邻接矩阵,访问速度很快。
dijkstra算法之优先队列优化的更多相关文章
- dijkstra算法与优先队列
这是鄙人的第一篇技术博客,作为算法小菜鸟外加轻度写作障碍者,写技术博客也算是对自己的一种挑战和鞭策吧~ 言归正传,什么是dijkstra算法呢? -dijkstra算法是一种解决最短路径问题的简单有效 ...
- dijkstra算法的堆优化
普通的dijkstra算法模板: //数据结构 int g[LEN][LEN]; //邻接矩阵 int vis[LEN]; //标记是否访问 int dist[LEN] //源点到各点的距离 fill ...
- 单源最短路径:Dijkstra算法(堆优化)
前言:趁着对Dijkstra还有点印象,赶快写一篇笔记. 注意:本文章面向已有Dijkstra算法基础的童鞋. 简介 单源最短路径,在我的理解里就是求从一个源点(起点)到其它点的最短路径的长度. 当然 ...
- Dijkstra普通算法及优先队列优化
#include<stdio.h> #include<iostream> #define maxv 100 #define inf 0x3fffffff using names ...
- 单源最短路-dijkstra算法(未优化)
bool used[maxn]; int g[maxn][maxn]; // 边未联系的填充为INF int d[maxn]; void dijkstra(int s){ memset(g,false ...
- 【Luogu P4779】dijkstra算法的堆优化
Luogu P4779 利用堆/优先队列快速取得权值最小的点. 在稠密图中的表现比SPFA要优秀. #include<iostream> #include<cstdio> #i ...
- 基于STL优先队列和邻接表的dijkstra算法
首先说下STL优先队列的局限性,那就是只提供入队.出队.取得队首元素的值的功能,而dijkstra算法的堆优化需要能够随机访问队列中某个节点(来更新源点节点的最短距离). 看似可以用vector配合m ...
- POJ 3268 Silver Cow Party 最短路—dijkstra算法的优化。
POJ 3268 Silver Cow Party Description One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numbe ...
- Dijkstra算法优先队列实现与Bellman_Ford队列实现的理解
/* Dijkstra算法用优先队列来实现,实现了每一条边最多遍历一次. 要知道,我们从队列头部找到的都是到 已经"建好树"的最短距离以及该节点编号, 并由该节点去更新 树根 到其 ...
随机推荐
- notepad++ 正则表达式(记录)
删除操作notepad++去掉行尾空格或逗号查找目标:\s+$ (或,+$)替换为空Note: 以换行符结尾表示是$\r\n,而不是\r\n$ notepad++删除文本文件里面的空白行查找目标:^[ ...
- python生成密码字典
import itertools as its words = 'abcdefghijklmnopqrstuvwxyz1234567890' r = its.product(words, repeat ...
- VS2013配置curl
http://blog.csdn.net/totodum/article/details/51059380 安装完成之后,要注意url的传值, curl中需要传char*
- 人工智能AI------有限状态机、分层状态机、行为树
https://www.cnblogs.com/zhanlang96/p/4793511.html 人工智能遵循着:感知->思考->行动决策方法:有限状态机(Finite-State Ma ...
- ps和top进程监控
一.名词解释 1.什么是进程(what is process)? 答:进程是程序运行的过程,伴有动态,生命和运行状态.(组成:1.已分配内存的地址空间 2.安全属性,包括所有权凭据和特权 3.程序 ...
- 【数字图像处理】Bilateral Filters
[数字图像处理]Bilateral Filters https://www.yuque.com/lart/idh721/bf 简单介绍 双边滤波是一种非线性的可以模糊图像并且能保留一定的边缘信息的技术 ...
- redis学习(三)
如何保障reids的数据安全和性能? 一.持久化选项 1.快照snapshotting 它可以将存在于某一时刻的所有数据都写入硬盘里面. 配置选项示例: save 60 1000 注:从最近一次创 ...
- JS ----- 底层原理
什么是JS JavaScript是一种基于对象的动态.弱类型脚本语言(简称JS),是一种解释型语言,和其他的编程语言不同,如java/C++等编译型语言,这些语言在代码执行前会进行通篇编译,先编译成字 ...
- 20191128 Spring Boot官方文档学习【目录】
Spring Boot文档 入门 使用Spring Boot 3.1. 构建系统 3.2. 结构化代码 3.3. 配置类 3.4. 自动配置 3.5. Spring beans和依赖注入 3.6. 使 ...
- CF140C New Year Snowmen(贪心+优先队列)
CF140C 贪心+优先队列 贪心策略:每次取出数量最多的三种球,合成一个答案,再把雪球数都-1再插回去,只要还剩下三种雪球就可以不断地合成 雪球数用优先队列维护 #include <bits/ ...