详解Dijkstra算法原理及其C++实现

详解Dijkstra算法原理及其C++实现

前言

Dijkstra算法是一种常见的求解单源最短路径的算法,本文将对其进行详细的讲解。

原理

Dijkstra算法的核心思想是贪心,即每次都选择当前最短路径上距离起点最近的顶点,并通过该顶点更新与其相邻的顶点的距离。Dijkstra算法使用一个数组dist[i]来记录起点到每个顶点的最短距离,同时使用一个visited[i]数组来记录每个顶点是否被访问过。

具体步骤可概括为:

  1. 初始化:将起点s加入集合S,将起点到每个顶点的距离dist[i]初始化为无穷大,将visited[i]初始化为false。
  2. 更新:从集合V-S中选择距离起点s最近的顶点u,将u加入集合S,对于与u相邻的顶点v,若dist[u]+w(u,v)<dist[v],则更新dist[v]=dist[u]+w(u,v),其中w(u,v)表示边(u,v)的权值。
  3. 重复进行步骤2,直到所有顶点都被加入集合S。

Dijkstra算法的时间复杂度为O(n^2),但可以通过堆优化的方式将其优化到O(nlogn)。

C++实现

以下是Dijkstra算法的C++实现代码:

#include <iostream>
#include <vector>
#include <queue>
#include <cstring>

using namespace std;

const int MAXN = 1005;
const int INF = 0x3f3f3f3f;

int dist[MAXN], visited[MAXN];
vector<pair<int, int>> G[MAXN];

void Dijkstra(int s) {
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
    memset(dist, INF, sizeof(dist));
    dist[s] = 0;
    q.push({0, s});

    while (!q.empty()) {
        int u = q.top().second;
        q.pop();
        if (visited[u]) continue;
        visited[u] = 1;
        for (auto& v : G[u]) {
            int d = v.second;
            if (dist[v.first] > dist[u] + d) {
                dist[v.first] = dist[u] + d;
                if (!visited[v.first]) q.push({dist[v.first], v.first});
            }
        }
    }
}

int main() {
    int n, m;
    cin >> n >> m;

    for (int i = 1; i <= m; i++) {
        int u, v, w;
        cin >> u >> v >> w;
        G[u].push_back({v, w});
        G[v].push_back({u, w});
    }

    int s;
    cin >> s;
    Dijkstra(s);

    for (int i = 1; i <= n; i++) {
        if (dist[i] == INF) cout << "INF" << endl;
        else cout << dist[i] << endl;
    }

    return 0;
}

示例说明

示例1

输入:

5 6
1 2 10
1 3 5
2 4 1
3 4 2
3 5 1
4 5 4
1

输出:

0
5
7
6
10

解释:

该图如下所示:

1 --10-- 2
|\     /
| 5\  /1
|   \/
|   /\
|2/   \4
v/     \
3 --2-- 5

起点为1,最短路径如下:

  • 1->2: 10
  • 1->3: 5
  • 1->4->2: 11
  • 1->4->3: 7
  • 1->4->5: 10

因此,输出结果为0 5 7 11 10。

示例2

输入:

4 4
1 2 3
1 3 5
2 4 4
3 4 2
1

输出:

0
3
5
7

解释:

该图如下所示:

1 --3-- 2
|\     /
| 5\  /4
|   \/
|   /\
|2/   \4
v/     \
3 --2-- 4

起点为1,最短路径如下:

  • 1->2: 3
  • 1->3: 5
  • 1->2->4: 7
  • 1->3->4: 7

因此,输出结果为0 3 5 7。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解Dijkstra算法原理及其C++实现 - Python技术站

(0)
上一篇 2023年5月22日
下一篇 2023年5月22日

相关文章

  • C++中new和delete匹配使用过程详解

    C++中new和delete匹配使用过程详解 什么是new和delete 在C++中使用new和delete可以动态地分配和释放内存。 new运算符从堆中分配一块大小的内存,而delete运算符则将分配的内存释放。 new的使用 我们可以使用new运算符动态地分配堆内存。其中,new会在堆中分配指定大小的内存,并返回该内存的地址,方便我们进行后续的使用。 以…

    C 2023年5月22日
    00
  • 详解json string转换为java bean及实例代码

    下面是“详解json string转换为java bean及实例代码”的完整攻略: 什么是JSON JSON是一种轻量级的数据交换格式,具有易读易写、占用带宽小、易解析和支持多种语言等优点。在Web开发中,常用于数据传输和Web API。 JSON to Java Bean 转换 在Java中,我们可以通过JSON的转换将JSON字符串转换成Java Bea…

    C 2023年5月23日
    00
  • 基于C语言自制华容道游戏的示例代码

    首先需要说明的是,华容道是一种古老的拼图游戏,通常用于测试思维策略和空间认知能力。现在我将为你提供一份基于C语言自制华容道游戏的示例代码攻略。 1. 游戏介绍 华容道游戏是一款将不同大小的方块放置在一个方格中的游戏,最终目标是将一块木板上的关键方块移动到棋盘的出口处。游戏规则简单,但是有很多不同的问题需要解决,从而使得这个游戏成为一个极好的思维训练工具。 2…

    C 2023年5月24日
    00
  • C语言实现最小生成树构造算法

    C语言实现最小生成树构造算法攻略 最小生成树(Minimum Spanning Tree,MST)是一种求加权无向连通图的生成树的算法,其可以将连通图的n个顶点连接起来,形成一个权值最小的树。本文将介绍使用C语言实现最小生成树构造算法的攻略。 算法简介 其中,Kruskal算法和Prim算法是最常用的两个求解最小生成树的算法。 Kruskal算法 Krusk…

    C 2023年5月22日
    00
  • N点虚拟主机管理系统出现错误代码-100001的解决方法

    N点虚拟主机管理系统出现错误代码-100001的解决方法 问题描述 在使用N点虚拟主机管理系统时,用户可能会遇到错误代码-100001,这通常是由于N点虚拟主机管理系统的一些配置问题引起的。 解决方法 1. 检查配置文件 首先,您需要检查配置文件,确保所有必要的参数设置正确。如果配置文件中存在错误或缺失,可能会导致错误代码-100001的出现。按照以下步骤进…

    C 2023年5月22日
    00
  • Caused by: java.lang.ClassNotFoundException: org.apache.commons.collections.Transformer异常

    框架或应用程序在启动或执行时,可能会抛出各种异常。其中一个常见异常是 java.lang.ClassNotFoundException,这种异常通常表示由类装入器试图加载某个类,但在加载类时未找到相应的类。 当我们的应用程序或框架抛出了 java.lang.ClassNotFoundException: org.apache.commons.collecti…

    C 2023年5月23日
    00
  • java抛出异常的几种情况小结

    让我详细讲解一下“Java抛出异常的几种情况小结”的完整攻略。 1. Java抛出异常的概念 Java中的异常是指在程序运行时发生了错误或异常情况而无法正常执行的情况。简单来说,当程序出现意料之外的错误或者问题,抛出异常是必须的。 2. Java异常的分类 Java异常可以分为两类:检查异常和非检查异常。 2.1 检查异常 当程序出现问题时,会产生一个检查异…

    C 2023年5月23日
    00
  • Android中gson、jsonobject解析JSON的方法详解

    Android中gson、jsonobject解析JSON的方法详解 什么是JSON JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,它基于JSON的数据格式来描述数据对象。JSON是一种数据存储格式,它和XML的作用类似,但JSON是一种轻量级的、更易于读写的数据格式。JSON中的数据可以是数组或对象,通过层级的…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部