C++实现Dijkstra算法

C++实现Dijkstra算法攻略

算法简介

Dijkstra算法是一个在加权图中查找单源最短路径的贪心算法。在开始时,所有节点被分为两个集合:已知最短路径的节点和未知最短路径的节点。对于未知最短路径的节点,算法通过已知最短路径的节点来更新这些节点到源点的距离,最终得到源点到图中所有节点的最短路径。

算法步骤

  1. 初始化图中所有节点的距离为无穷大,除源点的距离为0;
  2. 将所有节点加入未知节点集合;
  3. 从未知节点集合中选择一个最近的节点(即到源点距离最小);
  4. 更新该节点的所有邻居节点的距离,如果距离更短,则修改距离;
  5. 重复步骤3-4,直到所有节点均被加入已知节点集合。

C++实现示例:

以下是一个简单的使用邻接矩阵实现Dijkstra算法的示例,其中图的大小为5 * 5。我们以节点2作为源节点。

#include<bits/stdc++.h>
using namespace std;

const int N = 105;
const int INF = 999999;
int n, m;
int graph[N][N];  //邻接矩阵
int d[N];         //存储节点到源点的最短距离
bool vis[N];      //记录节点是否在已知节点集合中

//Dijkstra算法函数
void Dijkstra(int src) {
    memset(vis, 0, sizeof(vis));
    for (int i = 1; i <= n; i++) d[i] = graph[src][i];
    vis[src] = true;
    for (int i = 1; i < n; i++) {  //遍历除源点外的所有节点
        int u = -1, mn = INF;
        for (int j = 1; j <= n; j++) {
            if (!vis[j] && d[j] < mn) {
                u = j;
                mn = d[j];
            }
        }
        if (u == -1) return;  //无法到达目标点
        vis[u] = true;
        for (int j = 1; j <= n; j++) {
            if (!vis[j] && graph[u][j] != INF) {
                d[j] = min(d[j], d[u] + graph[u][j]);
            }
        }
    }
}

int main() {
    cin >> n >> m;
    memset(graph, INF, sizeof(graph));
    for (int i = 1; i <= n; i++) graph[i][i] = 0;
    for (int i = 1; i <= m; i++) {
        int u, v, w;
        cin >> u >> v >> w;
        graph[u][v] = min(graph[u][v], w);  
        graph[v][u] = min(graph[v][u], w);  //无向图需要加上反向边
    }
    int src = 2;  //源点为2
    Dijkstra(src);
    for (int i = 1; i <= n; i++) {
        cout << d[i] << " ";
    }
    cout << endl;
    return 0;
}

第二个示例是使用邻接表实现Dijkstra算法,相比邻接矩阵每次更新节点的距离时速度更快。相同的,我们以节点2作为源节点。

#include<bits/stdc++.h>
using namespace std;

const int N = 105;
const int INF = 999999;
int n, m;
struct Edge{   //邻接表中的边
    int to, w;
    Edge(int u, int v):to(u),w(v){}
    bool operator < (const Edge &e) const {
        return w > e.w;
    }
};
vector<Edge> graph[N];  //邻接表
int d[N];               //存储节点到源点的最短距离
bool vis[N];            //记录节点是否在已知节点集合中

//Dijkstra算法函数
void Dijkstra(int src) {
    memset(vis, 0, sizeof(vis));
    memset(d, INF, sizeof(d));
    priority_queue<Edge> q;  //使用优先队列,堆优化
    q.push(Edge(src, 0));
    d[src] = 0;
    while(!q.empty()) {
        Edge u = q.top();
        q.pop();
        if(vis[u.to]) continue;
        vis[u.to] = true;
        for(int i = 0; i < graph[u.to].size(); i++) {
            Edge v = graph[u.to][i];
            if(vis[v.to]) continue;
            if(d[v.to] > d[u.to] + v.w) {  //松弛操作,更新距离
                d[v.to] = d[u.to] + v.w;
                q.push(Edge(v.to, d[v.to]));
            }
        }
    }
}

int main() {
    cin >> n >> m;
    for(int i = 1; i <= m; i++){
        int u, v, w;
        cin >> u >> v >> w;
        graph[u].push_back(Edge(v, w));
        graph[v].push_back(Edge(u, w));  //无向图需要加上反向边
    }
    int src = 2;  //源点为2
    Dijkstra(src);
    for(int i = 1; i <= n; i++) {
        cout << d[i] << " ";
    }
    cout << endl;
    return 0;
}

以上两个示例均可在O(n^2)的时间内求解单源最短路径。

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

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

相关文章

  • PHP设计模式概论【概念、分类、原则等】

    PHP设计模式概论 概念 设计模式是指在面向对象编程中用于解决特定问题的重复使用的经验总结。设计模式不是一个可直接转换成代码的解决方案,而是定义了一组通用的原则和规范,它们可以用于设计任何系统。 分类 设计模式可以分为三类:创建型、结构型和行为型。 创建型模式 创建型模式主要用于对象的创建,包括“工厂模式”、“抽象工厂模式”、“单例模式”、“原型模式”、“建…

    C 2023年5月22日
    00
  • 基于C语言实现随机点名器(附源码)

    基于C语言实现随机点名器(附源码)攻略 背景 在日常教学过程中,老师需要选择学生进行点名,但是传统的手工点名有些麻烦,而电子化的随机点名器则可以快速、方便地进行点名,提高了点名的效率。 组件 点名器的组成部分为三个部分:1. 学生名单(可采用文本文件实现存储);2. 随机数生成器(用于随机产生学生编号);3. 点名器(根据随机数生成器产生的随机数来选出学生进…

    C 2023年5月23日
    00
  • VS2019中CMake项目如何指定c++语言标准

    对于VS2019中的CMake项目,指定C++语言标准分为以下两种情况: 针对某个特定的C++源文件指定语言标准 针对整个项目指定C++语言标准 以下是详细的操作步骤: 针对某个特定的C++源文件指定语言标准: (1) 在该C++源文件中添加以下语句: #SET(CMAKE_CXX_STANDARD 17) 以上语句的含义就是将这个C++源文件设为使用C++…

    C 2023年5月23日
    00
  • 学习C语言的第一天

    今天学习C语言学习了三个部分: 第一个部分是软件环境的搭建,如何搭建一个项目 使用工具:visual studio 2010 搭建过程:新建项目、配置设置(主要是解决运行后一闪而过的问题) 第二部分是编写一个简单的C语言程序代码 #include<stdio.h> //引入头文件 io指的是输入与输出 int main(){ //不可少的入口函数…

    C语言 2023年4月18日
    00
  • 如何在在Vue3中使用markdown 编辑器组件

    以下是在Vue3中使用markdown编辑器组件的攻略: 安装markdown编辑器组件 我们可以使用vue-markdown-editor组件,这是一个基于Vue3的markdown编辑器组件。 在终端中输入下列命令安装: npm install vue3-markdown-editor –save 引入组件 在Vue3项目中,可以使用以下代码引入组件:…

    C 2023年5月23日
    00
  • C++自定义函数判断某年某月某日是这一年中第几天

    针对您的问题我可以提供以下攻略来实现“C++自定义函数判断某年某月某日是这一年中第几天”: 算法思路 判断某年某月某日是这一年中第几天可以分解成以下几个步骤: 判断该年是不是闰年。 累加从1月到该月的天数。 如果是闰年且该月大于2月,天数再加1。 最后加上该月自身的天数。 返回累加的天数。 可以通过一个自定义函数来实现上述算法,该函数名称可以是getDayO…

    C 2023年5月23日
    00
  • 利用c++编写简易版2048小游戏

    利用C++编写简易版2048小游戏攻略 1. 程序概述 2048是一款经典的数字游戏,玩家在4*4的棋盘上操作数字合并,最终得到2048为胜利。我们可以使用C++编写一个简易版的2048小游戏,让用户可以通过控制台进行游戏。 2. 实现步骤 2.1 定义游戏类 我们首先需要定义一个游戏管理类,用于管理游戏的所有操作。在类的定义中包含如下属性和方法: 2.1.…

    C 2023年5月23日
    00
  • C语言菜鸟基础教程之Hello World

    C语言菜鸟基础教程之Hello World 什么是C语言? C语言是一种通用的高级程序设计语言,它能够方便地对计算机进行底层操作,如硬件控制和内存访问等。同时由于其简洁、高效和强大的特性,C语言在操作系统、编译器、游戏开发等领域得到了广泛的应用。 Hello World实例 下面以经典的Hello World程序为例,让我们一步步地学习如何使用C语言进行编程…

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