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

yizhihongxing

详解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语言:函数

    一篇文章带你入门C语言: 函数 函数的定义 函数是 C 语言中组织代码的一种主要方式。在 C 中,函数是由一系列语句组成的代码块,这些语句被命名并可以通过一个函数名来调用。 返回类型 函数名(参数列表) { // 函数体 } 返回类型:函数执行后返回的数据类型,例如 int、float 等。 函数名:函数的名称,可以根据函数的功能进行命名。 参数列表:函数执…

    C 2023年5月23日
    00
  • Visual Studio Code (vscode) 配置 C / C++ 环境的流程

    Visual Studio Code(以下简称VSCode)是一个强大的代码编辑器,它支持多种编程语言,包括C/C++。本篇攻略将会详细讲解在VSCode中配置C/C++环境的流程。 安装 C / C++插件 首先,你需要在VSCode中安装C/C++插件来加强其与C/C++语言的兼容性。在VSCode的插件市场中搜索”C/C++”,然后点击”安装”完成安装…

    C 2023年5月23日
    00
  • 剑网3明教怎么玩_剑网3明教贯木流PVE输出攻略(必看)

    剑网3明教怎么玩 简介 《剑网3》作为一款以武学为主题的MMORPG游戏,拥有多个门派供玩家选择。其中明教门派以其独树一帜的特点,备受玩家们的喜爱。本攻略将为大家介绍明教门派的PVE输出攻略,帮助各位玩家更好地在游戏中玩转明教职业。 明教门派的特点 明教门派主修内功心法,拥有较高的爆发输出和回复能力 明教的操作非常流畅,配合技能后摇短,能够进行多种连招输出 …

    C 2023年5月22日
    00
  • Java进阶:JNI使用技巧点滴

    Java进阶: JNI使用技巧点滴 什么是JNI Java Native Interface(JNI)是Java平台的一个重要特性,它允许Java应用程序调用本地(C、C++)应用程序,并且本地应用程序也可以调用Java应用程序。通过JNI,Java程序员可以使用Java的优点和C的优点,实现可以同时具有可移植性和性能的应用程序。 JNI允许在Java虚拟机…

    C 2023年5月23日
    00
  • C语言函数调用底层实现原理分析

    C语言函数调用底层实现原理分析,从根本上就是在探究内存是如何管理和运用的。下面我们将介绍在函数调用时,C语言底层的实现原理,并给出两个具体的示例说明。 函数调用栈的实现 在C语言中,函数调用涉及到堆栈的概念。堆栈是一种数据结构,它具有后进先出(LIFO)的特点。当函数被调用时,程序会将当前函数的返回地址(即下一个要执行的指令地址)以及其他一些信息(例如参数值…

    C 2023年5月23日
    00
  • 关于Http持久连接和HttpClient连接池的深入理解

    关于Http持久连接和HttpClient连接池的深入理解 什么是Http持久连接 在Http1.0中,每次客户端想要请求内容时,都会和服务器建立一次连接,产生一次完整的Http事务。连接关闭后,所有的相关资源被释放。 在Http1.1中,为了提高效率,引入了持久连接,即同一个连接可以请求多个资源。所以,Http持久连接可以理解为,在同一个连接上可以发送多个…

    C 2023年5月22日
    00
  • 一问学会QT时间类

    如何学习QT时间类 一、了解QT时间类 QT时间类是QT框架提供的一个用于处理时间的类,它提供了很多便捷的方法来进行时间计算和转换,并且支持不同的时间格式。其中最常用的时间类有QDateTime、QTime和QDate。 二、基本使用方法 2.1 获取当前时间 使用QDateTime::currentDateTime()函数可以获取当前的时间。 QDateT…

    C 2023年5月23日
    00
  • Fate/EXTELLA启动应用程序错误怎么办 0xc000007b错误的解决方法

    Fate/EXTELLA启动应用程序错误解决方案 问题描述 当尝试启动Fate/EXTELLA游戏时,可能会出现以下错误: “无法启动应用程序程序,因为计算机上找不到XXX.dll。请尝试重新安装该程序以解决该问题。” “应用程序无法正确启动(0xc000007b)。单击确定关闭应用程序。” 如果你在运行Fate/EXTELLA时遇到以上错误,那么你所面临的…

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