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算法用优先队列来实现,实现了每一条边最多遍历一次. 要知道,我们从队列头部找到的都是到 已经"建好树"的最短距离以及该节点编号, 并由该节点去更新 树根 到其 ...
随机推荐
- DatePicker 日期选择器
用于选择或输入日期 选择日 以「日」为基本单位,基础的日期选择控件 基本单位由type属性指定.快捷选项需配置picker-options对象中的shortcuts,禁用日期通过 disabledDa ...
- Day06:方法 / 猜字母游戏
JAVA方法 方法就是处理一个业务所需要编写的代码的代码段 方法特性 一个方法处理一个业务 方法代码编写,不和其他方法冲突 方法定义后可以随意调用 将main方法中的所有代码分散到各个普通方法中 减少 ...
- JMeter接口测试印象篇(win10)
参考博文1:https://www.cnblogs.com/suim1218/p/9257369.html 参考博文2:https://blog.csdn.net/u011541946/article ...
- C++随笔(0)——关于const
最近发现自己对const这一块其实不甚熟悉,所以复习一下const的相关知识点. 基本用法 const int bufSize = 512; 上面这样就可以将bufSize定义为常量,编译的时候编译器 ...
- linux 磁盘命令
用到共享软件为:samba 配置文件为 /etc/samba/smb.conf sudo fdisk -l 查看磁盘 sudo df -lh 查看磁盘挂载情况 sudo mount /dev/sdb ...
- 20191209 【归档】Linux就该这么学
学习背景 因为打算学习Redis和Docker,但是发现对Linux的操作已经完全忘记了,所以选择再学一次,但是不会深入的学习,选择了<Linux就该这么学>这本书,学完了感觉还挺好,但是 ...
- ArrayList(顺序表)和LinkedList(链表)的区别联系,优劣取舍问题
ArrayList和LinkedList都是List接口的实现类.主要区别如下: 最主要的区别是底层的数据结构不同: 1)ArrayList相当于一个动态数组,需要随机访问列表中的元素时,ArrayL ...
- 在CentOS 8 Linux中安装使用Cockpit服务器管理软件
在本文中,我们将帮助您在CentOS 8服务器中安装Cockpit Web 控制台,以管理和监视本地系统以及网络环境中的Linux服务器.您还将学习如何将远程Linux主机添加到Cockpit并在Ce ...
- hbase部署
Hbase: 更细的操作和原理研究笔记和视频 cloudera Hbase:https://sysit.cn/blog/post/sysit/cloudera%E5%AE%89%E8%A3%85HBA ...
- 多网卡的bond模式-把多个物理网卡绑定成一个逻辑上的网卡
参考: 多网卡的7种bond模式原理 如何实现网卡bond