Dijkstra's Algorithm分析以及其优化

最短路径算法|Dijkstra‘s Algorithm 最短路径问题几乎是每个计算机专业学生的必学知识点,相关的算法也比较多样,但其中最经典的肯定是由荷兰计算机科学家,1972年图灵奖得主Edsger Dijkstra于1959年发布的Dijkstra's Algorithm。如果值 sptSet[v] 为true,则顶点 v 包含在 SPT 中,否则不包含。数组 dist[] 用于存储所有顶点的最短距离值。最短路径问题简单来说就是给定一个图和图中的一个源顶点,找到从源到给定图中所有顶点的。以下子图显示了顶点及其距离值,仅显示了具有有限距离值的顶点。 阅读详情
Dijkstra's  Algorithm


传统的Dijkstra:
适用于单源无负权边最短路问题。
算法步骤:
a.初始时,S只包含源点,即S={v},v的距离为0。
U包含除v外的其他顶点,即:U={其余顶点},若v与U中顶点u有边,则<u,v>正常有权值,
若u不是v的出边邻接点,则<u,v>权值为∞。
b.从U中选取一个距离v最小的顶点k,把k,加入S中(该选定的距离就是v到k的最短路径长度)。
c.以k为新考虑的中间点,修改U中各顶点的距离;
若从源点v到顶点u的距离(经过顶点k)比原来距离(不经过顶点k)短,
则修改顶点u的距离值,修改后的距离值的顶点k的距离加上边上的权。
d.重复步骤b和c直到所有顶点都包含在S中。

//核心代码:
void  Dijkstra(int  s,int t)//s为起点
{//t为终点
    int temp, k;
    ans=-1;
    for (int i=0; i<n; i++)//对起点邻点操作
    {
        dis[i]=map[s][i];
        vis[i]=0;
    }
    dis[s]=0;
    vis[s]=1;//说明s点已被标记
for (int i=0; i<n; i++)
    {
        temp = inf;//inf为超大的数
        for (int j=0; j<n; j++)
        {
if(vis[j]==0 && temp > dis[j])
            {//j没有被标记且是已知点最小的
                k=j;
                temp=dis[j];
            }
        }
        if(temp == inf) //说明全被标记
            break;
        vis[k]=1;
        for (int j=0; j<n; j++)
        {//看通过k点是否会取得更小值
            if(dis[j] > dis[k] + map[k][j])
                dis[j]=dis[k]+map[k][j];
        }
    }
    if(dis[t]!=inf)
        ans = dis[t];
}


传统dijkstra的不足之处:
(1)用邻接矩阵arcs来存储网络图,其存储量为
NxN。对于大型稀疏矩阵,这将耗费大量资源存储那些
无意义的矩阵元素。
(2)当从未标记节点集合T选定下一个节点vj作
中间节点后,在更新操作过程中,需要扫描所有的未标
记节点并进行比较更新。而未标记节点集合T中往往
包含大量与中间节点V;不直接相连的节点。
(3)在选择下一个最短路径节点作为中间节点时,
需要比较所有的未标记节点。而这个中间节点往往包含
在与已标记节点S集合的所有节点邻接的节点中。
(4)在算法的每次迭代中,由于未标记节点以无序
的形式存放在一个链表中或一个数组中.每次选择最短
路径节点都必须将所有未标记节点扫描一遍,当节点数
目很大时,这无疑将成为制约计算速度的关键冈素。



基于优先队列的优化

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<stack>
#include<queue>
#include<vector>
using namespace std;


#define INF  0x3f3f3f3f   //定义一个很大的数  


struct Node
{
    int num,val;   //存放结点编号和到初始点的距离
} nod;


priority_queue<Node> qq;;   //优先从小到大


bool operator < (Node a,Node b)
{
    if(a.val == b.val) return a.num>b.num;
    return a.val>b.val;              //先出小
}


int book[100];  //检查这个点是否用过
int dis[100];     //到原点最短距离
int D[100][100];  //记录路径长度
int V,E;


int main()
{
    int a,b,d;
    while(cin>>V>>E && V&& E)  //输入顶点数和边数
    {
        while(!qq.empty()) qq.pop(); //清空
        memset(book,0,sizeof(book));
        memset(D,-1,sizeof(D));

        for(int i=0; i<E; i++)
        {
            cin>>a>>b>>d;
            D[a][b] = D[b][a] = d;
        }

        for(int i=2; i<=V; i++)
            dis[i]=INF;

        dis[1]=0;
        nod.num=1;
        nod.val=0;

        qq.push(nod);   //将起点放入队列

        while(!qq.empty())  //不为空时
        {

            for(int i=2; i<=V; i++)
            {
                if(D[qq.top().num][i] != -1  &&dis[i]>dis[qq.top().num] + D[qq.top().num][i])
                {

                    dis[i]=dis[qq.top().num] + D[qq.top().num][i];
                    nod.num=i;
                    nod.val=dis[i];
                    qq.push(nod);
                }
            }

            qq.pop();
        }

        for(int i=1; i<=V; i++)
        {
            cout<<"初始点到"<<i<<"点的距离为:"<<dis[i]<<endl;
        }

    }
    return 0;
}

完全优化后空间复杂度可以从O(N*N)到O(4*N+E),时间复杂度可以从O(N*N)到O(n*(logN+E),具体复杂度分析不在此解析,详情可见参考论文。
在此只是在时间复杂度上有一定的优化,空间复杂度的优化可以用邻接表进行对边的存储。堆优化以及空间优化将在后续更新。




本文参考:王战红1 孙明明2姚 瑶3《Dijkstra算法的分析与改进》的论文。


数据结构--迪杰斯特拉(Dijkstra)算法 迪杰斯特拉算法 ,建议收藏 ,反复观看。 阅读详情

相关推荐

迪杰斯特拉算法 Dijkstra‘s Algorithm 详解

迪杰斯特拉算法是一个简单而强大的算法,用于解决单源最短路径问题。本文介绍了该算法的基本原理,并提供了一个Java实现示例。使用迪杰斯特拉算法时需要注意,该算法不适用于带负权边的图,因为在负权边存在的情况下,最短路径可能不存在或需要更复杂的算法(如贝尔曼-福德算法)来解决。全文完!

十七次方 1553

DijkstraAlgorithm(迪杰斯特拉算法)

迪杰斯特拉(Dijkstra)算法介绍 迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个结点到其他结点的最短路径。 它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止。 最短路径 最短路径问题是图论研究中的一个经典算法问题,旨在寻找图(由结点和路径组成的)中两结点之间的最短路径,大致可以分为如下几种问题,可无论如何分类问题,其本质思想还是不变的,即,求两点间的最短距离。 a) 确定起点的最短路径问题 - 即已知起始结点,求最短路径的问题。 b) 确定终点的最短

colzry的博客 1万+

Dijkstra算法与城市最短路问题详解

最短路算法是图论中的基础问题,用于求解图中两点间的最短路径。Dijkstra算法作为经典的单源最短路算法,采用贪心策略,通过优先队列实现高效搜索。这类算法在导航系统、物流配送等实际场景中有广泛应用。信息学竞赛中常考察Dijkstra及其变种,同时还需掌握Floyd、Bellman-Ford等其他最短路算法。理解不同算法的原理和适用场景,能帮助开发者根据图结构特点选择最优解法,提升路径规划效率。

weixin_33727510的博客 460

迪杰斯特拉算法(Dijkstra‘s algorithm)以及示例

迪杰斯特拉算法是用于求最短路径的一种算法。注意迪杰斯特拉算法只适用于有向图或者边权非负的无向图,如果边权有负数,则需要使用其他算法,如贝尔man-福德算法。最终得到的最短路径为:1: 0, 2: 3, 3: 4, 4: 3, 5: 5。可以看到结点1到结点4的最短路径为1 -> 2 -> 4,距离为3。设置起点1的最短路径为0,并开始更新周围结点的最短路径。假设有一张图如下,求从结点1到结点4的最短路径。更新 2: 1+2=3, 3: 1+3=4。更新 4: 2+1=3, 5: 2+3=5。

MOMO203010532的博客 2420

Dijkstra算法在紧急救援路径规划中的实战应用

Dijkstra算法作为图论中的经典单源最短路径算法,通过贪心策略逐步扩展当前最短路径节点,在非负权图中具有最优性保证。该算法广泛应用于网络路由、物流配送等需要最短路径计算的场景,其时间复杂度通过优先队列优化可降至O((V+E)logV)。在应急调度等实际工程问题中,常需在保证路径最短的同时优化第二目标(如救援队数量最大化),这需要扩展传统Dijkstra的实现方式。以PTA L2-001紧急救援题目为例,通过邻接表存储图结构、维护多维度节点属性(距离/救援队数/路径数),并处理等长路径时的多条件判断,展示

weixin_33831673的博客 426

24、Dijkstra‘s Algorithm: Finding the Shortest Path in Weighted Graphs

本博客深入解析了Dijkstra算法的原理、实现步骤及其在加权图中寻找最短路径的应用。从基础概念到详细执行过程,再到C语言代码实现,内容涵盖算法步骤、可视化流程、性能分析、优化策略以及实际应用场景如网络路由和交通导航系统。此外,还比较了Dijkstra与其他最短路径算法(如Bellman-Ford、Floyd-Warshall和A*),并讨论了其局限性和处理特殊情况的方法。适用于希望掌握图论算法及其实战应用的开发者和技术爱好者。

u5v6w7的博客 193

The Dijkstra Algorithm 算法解析

转自  http://www.cppblog.com/eryar/archive/2013/01/01/196897.html

qq1987924的专栏 839

TSEND_C指令错误代码解析与实战排错指南

本文详细解析西门子PLC中TSEND_C指令的常见错误代码,包括连接建立、参数配置、资源限制和网络通信等错误类型。针对错误代码80C4等典型问题提供实战排错指南,帮助工程师快速诊断和解决工业通信中的连接故障,提升系统可靠性。

backprop5master的博客 414

Bellman-Ford Algorithm and Dijkstra Algorithm

最近在看《挑战程序设计竞赛》,边看边整理一些知识,这篇内容是有关最短路径的几个主要的算法: Bellman-Ford Algorithm、Dijkstra Algorithm、Floyd-Warshall Algorithm 前两者主要是针对单源最短路问题,后者用来解决任意两点之间的最短路径以及求传递闭包问题的 1.Bellman-Ford Algorithm 这个算法的原理可

kornberg_fresnel的博客 581

Rk3568 百兆以太网RMII模式DTS配置详解

本文详细解析了RK3568芯片在百兆以太网RMII模式下的DTS配置方法,包括时钟树配置、PHY接口模式定义及实际工程中的进阶设置。通过实战案例和调试技巧,帮助开发者快速解决RMII模式下的常见问题,提升工业控制设备的网络稳定性。

weixin_29189377的博客 422

pi/4QPSK调制解调原理

文章目录1. π/4\pi/4π/4QPSK 信号的调制原理2. 匹配滤波器与成形滤波器 1. π/4\pi/4π/4QPSK 信号的调制原理 减小相位突变量的QPSK由偏置键控QPSK(OK-QPSK)和 π/4\pi/4π/4偏置的QPSK( π/4\pi/4π/4QPSK)。由于 π/4\pi/4π/4QPSK是用差分相位编码产生的(因此也叫做 π/4\pi/4π/4DQPSK),能有效地进行差分解调和鉴频器解调,在一些不易提取相干载波的场合很有用。 在常规的QPSK中,输入数据经过串/并变换后,分成

gemengxia的博客 2万+

Minimum Spanning Trees - Prim’s algorithm & Single-Source Shortest Paths - Dijkstra’s algorithm

前者用于最小生成树;后者用于单源最小路径搜索。 两者均通过维护待处理节点队列中的当前“最小”信息完成新节点的并入: 前者维护的是到部分树的最短距离;后者维护的是到源节点的最短距离。 前者用于最小生成树;后者用于单源最小路径搜索。 最小生成树算法:Kruskal,Prim 单源最小路径算法:Bellman-Ford,Dijkstra

wenwei202的专栏 1261

32、通用处理器通信平台发展与5G开源社区技术解析

本文探讨了基于通用处理器(GPP)的通信平台在5G技术中的发展现状与挑战,详细介绍了多个开源平台和硬件架构,并分析了软件加速方法和未来发展方向。文章指出,尽管GPP具有灵活性和开放性优势,但在实时信号处理和功耗等方面仍存在瓶颈,需要通过核心技术研发、标准化协作和应用拓展推动5G技术的实际应用。

orange的博客 128

单板电源设计(LDO、DC/DC)

高速电路设计的电源架构 在电路设计中,一块单板往往涉及多种电源,常见的如5V/3.3V/2.5V/1.8V/1.5V/1.2V/1V0.9V/0.75V等,如此多种类的电源不可能都直接通过背板从电源板获得。一般,单板仅有一种或者两种输入电源,如48V或12V,再由它们产生单板上器件所需要的电源。 单板如何由输入电源生成所需电源,常见有两种架构:集中式电源架构和分布式电源架构。 ...

sinat_15677011的博客 8331

基于STM32的太阳能充电宝设计_资料编号31

系统硬件包括主控 STM32F103C8T6、0.96 OLED 显示屏、蜂鸣器、电源自锁开关、温度传感器 DS18B20、继电器、5 V DC 升压模块 、TB4056、18650锂电池、9 V太阳能板、稳压降压 5 V三极管。电源供应:锂电池为系统供电,9 伏太阳能板经 5 伏降压稳压三极管降压为 5 伏后传送到 TP4056,TP4056 为锂电池供电,因锂电池电压 3.7 伏,通过 5 伏 DC 升压模块升压到 5 伏为整个系统提供 5 伏电压。

嵌入式阿齐Archie 1万+

poj1511+链式前向星+dijkstra堆优化

如果看题解往下划拉…… 这题网上说卡数据,只能链式前向星才能过?正好学一下链式前向星的处理 其实:这个和vector做的邻接表差不多。可能用起来会快一点?(不然这题邻接表为啥过不了) 我觉得dijkstra的堆优化和spfa算有非常强的关联性 这里提几句:(分析一下异同) spfa是一种基于bfs的单源最短路算法,起源于bellman-ford。 这个算法名是个梗,一个西南交大的哥们自称发现了这个...

qq_43450892的博客 351

从win系统远程使用服务器中的nsight system、nsight compute

本文介绍了如何在Windows系统中远程使用服务器上的Nsight System和Nsight Compute工具。主要内容包括:1)双系统同步安装相同版本的Nsight工具,配置环境变量;2)命令行生成profile文件或直接运行分析;3)Windows远程连接服务器的配置方法;4)解决权限问题的具体方案,如修改文件夹权限或调整NVIDIA驱动配置。文章提供了详细的安装步骤和常见问题解决方案,适用于需要进行GPU性能分析和调试的开发人员。

Justinyh的博客 401

Algorithm 最短路径之 Dijkstra的优化

Dijkstra算法利用了优先队列,也用到了静态邻接表。主要也是有两部分组成。一: 当然是初始化。将dist和pre分别赋值 ,然后输入各条边的信息,存储在静态邻接表中 。二: 中Dijkstra中 将Q.push(temp) .然后利用for(i = pre[nod] ; i != -1 ;i = edge[i].next )将每条与temp有关联的边进行遍历。能松弛的点push到Q中。详细看下

没有进步就是退步 599

目标检测YOLO实战应用案例100讲-【目标检测】缺陷检测(二)

在工业生产中总是经常遇到裂痕、划痕等产品的表面缺陷问题,机器视觉行业对于表面检测相比前几年已经有很大的突破,对于产品表面的划伤、污迹等检测已经不再是难点。在金属、玻璃、手机屏幕、液晶板等行业表面检测上应用广泛。但由于该类缺陷形状不规则、深浅对比度低,而且往往会被产品表面的自然纹理或图案所干扰。因此,表面划痕缺陷检测对于正确打光、相机分辨率、被检测部件与工业相机的相对位置、复杂的机器视觉算法等要求非常高。

qq_36130719的博客 728

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Dijkstra’s Shortest Path Algorithm / LeetCode 787. Cheapest Flights Within K Stops

Dijkstra’s Shortest Path Algorithm 实现详见:https://www.geeksforgeeks.org/dijkstras-shortest-path-algorithm-using-priority_queue-stl/ 需要注意的是,priority_queue并无法更新内部的元素,因此我们更新dist的同时,直接把新的距离加入pq即可。p...

weixin_30507269的博客 288

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Dijkstra算法原理、优化与应用场景详解

最短路径算法是图论中的基础算法,广泛应用于网络路由、交通导航等领域。Dijkstra算法作为经典的单源最短路径算法,通过贪心策略逐步确定从源点到各顶点的最短路径。其核心在于维护优先队列并不断松弛边权,时间复杂度取决于数据结构选择,如二叉堆实现可达O((V+E)logV)。工程实践中常结合CSR存储格式和并行计算优化性能,在OSPF路由协议和实时导航系统中发挥关键作用。针对负权边场景需要切换Bellman-Ford算法,而A*算法则通过启发式函数扩展了Dijkstra的应用范围。

weixin_34194087的博客 313

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

2_Dijkstra’s Algorithm_宾夕法尼亚大学机器人运动规划专项课程【学习笔记(附 Dijkstra’s Algorithm 代码获取链接)】

基于图搜的算法 Grassfire 算法(烧草算法) Dijkstra’s Algorithm The goal is to find a path for the start node A to the end node E that minimizes the sum of the weights

huangjunsheng123的博客 431

Dijkstra’s algorithm小结

温故而知新,可以为师矣。 141

SPFA+Dijkstra+Floyd Java模板

SPFA import java.util.Arrays; import java.util.LinkedList; import java.util.Queue; import java.util.Scanner; public class SPFA { static SE[] e = new SE[9999]; static int[] dis = new int[9999]; ...

weixin_45948204的博客 1335

DeepSeek 迪杰斯特拉算法(Dijkstra‘s Algorithm)

这个算法是图论和算法课程中的核心内容,理解它对于学习更复杂的最短路径算法(如Bellman-Ford、Floyd-Warshall)很有帮助。邻接表 + 二叉堆 O((V+E)logV) O(V+E) 稀疏图。2 A,D [0,4,2,1] 选距离最小的D,经D到B更短。3 A,D,C [0,3,2,1] 选C,经C到B更短。步骤 已确定顶点 距离数组[A,B,C,D] 说明。初始 A [0,∞,∞,∞] 源点A距离为0。1 A [0,6,2,1] 选择A,更新邻居。4 全部 [0,3,2,1] 完成。

m0_37843156的博客 644
上一篇: 搜索入门
下一篇: 优先队列-结构体重载
也道长
博客等级 码龄9年 11粉丝 52原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值