算法基础14 —— 图论入门之迪杰斯特拉算法(Dijkstra)

本文详细介绍了Dijkstra算法的原理和实现过程,包括其与Floyd算法的区别,以及在处理最短路径问题时的局限性,特别是对负权边的处理。通过实例展示了Dijkstra算法如何找到从一个起点到所有其他点的最短路径,并提供了AC代码模板。此外,还讨论了算法的时间复杂度和适用场景。
回顾
  • Floyed算法可以求任意两点之间的最短路径,但是Dijkstra算法只能求一个结点到另一个结点的最短路径,它是一个单源的最短路径算法
  • Floyed算法的时间复杂度为O(n^3),故一般情况下数据范围要求在100以内
Dijkstra算法描述
  • 设起点为s,dis[v]表示从s到v的最短路径长度, 如dis[3] = 6表示从起点到3号结点的最短路径为6
  • pre[v]为v的前驱节点,用来输出路径
  • 初始化:
dis[v] =(v ≠ s);//初始时路径为无穷 
dis[s] = 0;//s -> s的路径为0 
pre[s] = 0; 
  • 伪代码:
for (i = 1; i <= n ; i++)
{
   
   
    //1.在没有被访问过的点中找一个顶点u使得dis[u]是最小的
    //2.把u标记为已确定最短路径
    //3.For循环遍历:与u相连的每个未确定最短路径的顶点v
    //如果结点u的加入使得s->v的距离dis[v]变小,则更新
    if (dis[u] + w[u][v] < dis[v]) 
    {
   
   
        dis[v] = dis[u] + w[u][v];
        pre[v] = u;
    }
}

可以通过下图来理解为什么要更新dis[v] = dis[u] + w[u][v]
在这里插入图片描述

  • 算法结束:dis[v]为s到v的最短距离;pre[v]为v的前驱节点,用来输出路径。
算法的总体思想:

首先设置一个空集合,并且将所有的结点分成两类,一类是确定了最短路径的结点,另一类是未确定最短路径的结点。每次向集合中加入一个可以确定最短路的结点,然后判断会不会因为该点的加入使得某个结点到其他结点的距离变得更短,如果是,则更新最短距离。

这么多伪代码,是不是很抽象有点晕了?下面来看一个例子

Dijkstra算法举例

例:根据下图a,找出从节点1出发到各个节点的最短路径长度。
在这里插入图片描述

  • 算法开始时,作为起点的dis[1] = 0//结点1到其自身的距离为0
    结点1到其他结点的距离为无穷,即dis[i] = 0x3f3f3f3f
    在这里插入图片描述
    在这里插入图片描述

  • 第一轮循环发现dis[1] = 0最小,将结点1标记成已经确定最短路径的结点(1号结点的加入会影响1号结点到2、3和4号结点的距离)。另外还需要根据图a对所有的绿点做出修改,使得dis[2] = 2dis[3] = 4dis[4] = 7
    在这里插入图片描述
    在这里插入图片描述

  • 第二轮循环发现1号结点除外,dis[2] = 2最小,将结点2标记成已经确定最短路径的结点(2号结点的加入只会影响1号结点到3和5号结点的距离)。另外还需要根据图a对其余绿色结点做出修改,使得dis[3] = 3dis[5] = 4

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值