堆优化的dijkstra算法

本文介绍了基于贪心思想的Dijkstra算法,该算法仅适用于边长为非负数的图,拥有O(mlogn)的时间复杂度。流程包括初始化节点距离、选择未标记且距离最小的节点进行标记,并更新其相邻节点的距离,直至所有节点都被标记。

基于贪心思想,只适用于边长为非负数的图

O(mlogn)

算法流程

1.初始化的dist[1]=0,其余节点的dist为正无穷

2.找出一个未被标记、dist[x]最小的节点x并标记

3.扫描x的所有出边(x,y,z),若dist[y]>dist[x]+z,则更新dist[y]

4.重复2、3,直到所有节点被标记

//by ziwan Catherine
//堆优化dijkstra 边长为非负数 
//d[n]从起点到n的最短路 
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue> 
using namespace std; 
const int N=10010,M=1000010;
int head[N],ver[M],edge[M],next[M],d[N];
bool v[N];
int n,m,tot;
priority_queue< pair<int,int> > q;
//大根堆 优先队列 pair第一维为dist相反数(变成小根堆) 第二维为节点编号 
void dijkstra(){
	memset(d,0x3f,sizeof(d));
	d[1]=0;//dist初始化 起点为0,其余为正无穷
	memset(v,0,sizeof(v));//节点标记
	q.push(make_pair(0,1));
	while(q.size()){
		int x=q.top().second;q.pop();//取堆顶
		if(v[x]) continue;v[x]=1;
		for(int i=head[x];i;i=next[i]){//扫描所有出边
			int y=ver[i],z=edge[i];
			if(d[y]>d[x]+z) {
				d[y]=d[x]+z;
				q.push(make_pair(-d
### 使用优化Dijkstra算法 #### 1. 的作用及其优势 在未优化版本的Dijkstra算法中,每次选取当前距离最小的节点时都需要遍历整个候选列表,这使得时间复杂度较高。引入结构能够显著降低这一过程的时间开销。斐波那契作为一种特别设计的数据结构,在处理动态集合方面表现出色,尤其适合于频繁执行插入和减少键值的操作场景下使用[^1]。 对于标准二叉而言,其支持O(log n)时间内完成插入、删除最小元素等基本操作;而斐波那契则可以在摊还意义上达到更好的性能指标——插入新结点只需常数级时间O(1),减小某个已存在结点的关键字也只需要均摊意义上的O(1)。 #### 2. Java实现带优化Dijkstra算法 下面给出一段基于优先队列(这里采用Java内置PriorityQueue类模拟简单形式下的行为)来加速查找最短路径的过程: ```java import java.util.*; public class DijkstraWithHeap { private static final int INFINITY = Integer.MAX_VALUE; public static void main(String[] args){ List<List<Node>> adjacencyList = new ArrayList<>(); initializeGraph(adjacencyList); // 初始化图数据 dijkstraAlgorithm(adjacencyList,0); } public static void dijkstraAlgorithm(List<List<Node>> adj,int startVertex){ PriorityQueue<Node> pq = new PriorityQueue<>(Comparator.comparingInt(node -> node.distance)); int V = adj.size(); boolean[] visited = new boolean[V]; Arrays.fill(visited,false); int[] distTo = new int[V]; Arrays.fill(distTo,INFINITY); distTo[startVertex]=0; Node sourceNode=new Node(startVertex,distTo[startVertex]); pq.add(sourceNode); while(!pq.isEmpty()){ Node u=pq.poll(); if (!visited[u.vertex]){ visited[u.vertex]=true; for (Node v : adj.get(u.vertex)){ relaxEdge(u,v,pq,distTo); } } } } private static void relaxEdge(Node from, Node to, Queue<Node> queue, int[] distances){ if(to!=null && !to.equals(from)){ int alt=distances[from.vertex]+to.weight; if(alt<distances[to.vertex]){ distances[to.vertex]=alt; queue.removeIf(n->n.vertex==to.vertex); queue.offer(new Node(to.vertex,alt)); } } } static class Node{ int vertex; int weight; int distance; public Node(int vertex, int distance){ this.vertex=vertex; this.distance=distance; } } private static void initializeGraph(List<List<Node>> graph){ /* 图初始化逻辑 */ } } ``` 此代码片段展示了如何利用`PriorityQueue`作为简易替代品来近似实现斐波那契的功能特性,从而加快Dijkstra算法运行速度。实际应用中可根据需求选用更适合的具体型态,比如手写版斐波那契以获取更佳效能表现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值