Dijkstra算法求最短路

news2024/10/5 13:59:25

Dijkstra算法是单源最短路算法,是用来求一个点到其他所有点点最短距离,使用小根堆优化后时间复杂度大概为 O m l o g n Omlogn Omlogn

注意:不可以解决存在负权边的问题

【模板】单源最短路径(标准版)

链接:https://www.luogu.com.cn/problem/P4779

题目描述

给定一个 n n n 个点, m m m 条有向边的带非负权图,请你计算从 s s s 出发,到每个点的距离。

数据保证你能从 s s s 出发到任意点。

输入格式

第一行为三个正整数 n , m , s n, m, s n,m,s
第二行起 m m m 行,每行三个非负整数 u i , v i , w i u_i, v_i, w_i ui,vi,wi,表示从 u i u_i ui v i v_i vi 有一条权值为 w i w_i wi 的有向边。

输出格式

输出一行 n n n 个空格分隔的非负整数,表示 s s s 到每个点的距离。

样例 #1

样例输入 #1

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

样例输出 #1

0 2 4 3

提示

1 ≤ n ≤ 1 0 5 1 \leq n \leq 10^5 1n105

1 ≤ m ≤ 2 × 1 0 5 1 \leq m \leq 2\times 10^5 1m2×105

s = 1 s = 1 s=1

1 ≤ u i , v i ≤ n 1 \leq u_i, v_i\leq n 1ui,vin

0 ≤ w i ≤ 1 0 9 0 \leq w_i \leq 10 ^ 9 0wi109,

0 ≤ ∑ w i ≤ 1 0 9 0 \leq \sum w_i \leq 10 ^ 9 0wi109

思路-朴素

  1. 初始化时,dist[]数组全部初始化为无穷大,dist[1]=0
  2. 从圈中选择一个距离最小的点u,打上标记st[u]=1表示这个点出圈
  3. u的所有出边进行松弛操作【尝试更新相邻点的最小距离】
  4. 重复2,3步骤,直到圈内为空

代码- O ( n 2 ) O(n^2) O(n2)

下面代码是用邻接矩阵求1-n的最短路

#include <iostream>
#include<cstring>
using namespace std;

const int N = 510;

int g[N][N]; //为稠密阵所以用邻接矩阵存储
bool st[N];//用于记录该点的最短距离是否已经确定
int dist[N]; //用于记录每一个点距离第一个点的距离
int n, m;

int Dijkstra()
{
	memset(dist, 0x3f, sizeof dist);
	dist[1] = 0; //第一个点到自身的距离为0
	for (int i = 0; i < n; ++i)
	{
		int u = i; //当前访问的点
		for (int j = 1; j <= n; j++) if (!st[j] && dist[j] < dist[u]) u = j; //寻找距离最小的点
		st[u] = true;
		//依次更新每个点所到相邻的点路径值
		for (int j = 1; j <= n; j++) dist[j] = min(dist[j], dist[u] + g[u][j]);
	}
	if (dist[n] == 0x3f3f3f3f) return -1; //不存在
	return dist[n];
}

int main()
{
	cin >> n >> m;
	memset(g, 0x3f, sizeof g);
	while (m--)
	{
		int x, y, z;
		cin >> x >> y >> z;
		g[x][y] = min(g[x][y], z); //如果发生重边的情况则保留最短的一条边
	}
	cout << Dijkstra() << endl;
	return 0;
}

思路-堆优化

算法的主要耗时的步骤是从dist 数组中选出:没有确定最短路径的节点中距离源点最近的点 t

只是找个最小值而已,没有必要每次遍历一遍dist数组。所以这里可以使用小根堆来维护。

代码- O ( m l o g n ) O(mlogn) O(mlogn)

#include <bits/stdc++.h>

#define int long long
using namespace std;

const int N = 1e5 + 10;
typedef pair<int, int> PII;
typedef struct edge {
    int y, w;
} edge;

vector<edge> e[N];
int dist[N];
bool st[N];
int n, m, s;

void Dijkstra() {
    priority_queue<PII, vector<PII>, greater<>> q;
    q.push({0, s});
    for (int i = 1; i <= n; i++) dist[i] = 1e18;
    dist[s] = 0;
    while (q.size()) {
        auto [d, x] = q.top();
        q.pop();
        if (st[x]) continue;
        st[x] = true;
        for (auto [y, w]: e[x]) {
            if (dist[y] > dist[x] + w) {
                dist[y] = dist[x] + w;
                q.push({dist[y], y});
            }
        }
    }
}

signed main() {
#ifndef ONLINE_JUDGE
    freopen("test.in", "r", stdin);
    freopen("test.out", "w", stdout);
#endif
    cin >> n >> m >> s;
    while (m--) {
        int a, b, c;
        cin >> a >> b >> c;
        e[a].push_back({b, c});
    }
    Dijkstra();
    for (int i = 1; i <= n; i++) {
        cout << dist[i] << " ";
    }


    return 0;
}

Codeforces Alpha Round 20 (Codeforces format)-C. Dijkstra?

题目

image-20230611131955834

思路

Dijkstra算法的模版题目,这里需要求从1走到n到最短路径长度,

  • 可以先跑一遍Dijkstra算法
  • 然后从终点开始往前找是从哪个点转移过来的,即满足dist[x]=dist[y]+w,y为x的邻点,w为边权
  • 最后需要把路径反转一下

代码

#include <bits/stdc++.h>
#define int long long
#define yes cout << "YES" << endl;
#define no cout << "NO" << endl;
using namespace std;

typedef pair<int, int> PII;
const int N = 1e5 + 10;
typedef struct edge {
    int to, w;
} edge;

vector<edge> e[N];
int dist[N];
bool st[N];
int n, m;

void dijkstra() {
    priority_queue<PII, vector<PII>, greater<>> q;
    q.push({0, 1});
    for(int i=1;i<=n;i++){
        dist[i]=1e18;
    }
    dist[1] = 0;
    while (q.size()) {
        auto [distance, x] = q.top();
        q.pop();
        if (st[x])
            continue;
        st[x] = true;
        for (auto [y, w] : e[x]) {
            if (dist[x] + w < dist[y]) {
                dist[y] = dist[x] + w;
                q.push({dist[y], y});
            }
        }
    }
}
void solve() {
    cin >> n >> m;
    while (m--) {
        int a, b, c;
        cin >> a >> b >> c;
        e[a].push_back({b, c});
        e[b].push_back({a, c});
    }
    dijkstra();

    if (dist[n] == 1e18) {
        cout << -1 << endl;
    } else {
        int t = dist[n];
        vector<int> path;
        path.push_back(n);
        int x = n;
        while (t != 0) {
            for (auto [y, w] : e[x]) {
                if (dist[x] == dist[y] + w) {
                    path.push_back(y);
                    x = y;
                    t-=w;
                    break;
                }
            }
        }
        reverse(path.begin(),path.end());

        for(auto x:path){
            cout<<x<<" ";
        }
    }
}
signed main() {
    int _ = 1;
    while (_--)
        solve();
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/633636.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用CRM系统通过四点快速收集客户信息

CRM是客户关系管理的缩写&#xff0c;它可以帮助企业管理销售、营销和客户服务&#xff0c;提升管理能力&#xff0c;获得更多收益。 那么&#xff0c;在CRM系统中客户是什么&#xff1f;如何快速收集客户信息呢&#xff1f;下面我们来说一说。 一、CRM中的客户是什么&#xf…

Java012——String引用数据类型的简单学习

回顾Java数据类型 本次要学习的是Java引用数据类型String 一、对String类简单说明 说明&#xff1a;String是Java中的一个类 二、String类的作用 作用&#xff1a;主要用来创建和操作字符串。 三、使用String类 3.1、创建字符串 注意&#xff1a; 1、字符串使用双引号&qu…

shell脚本:文本三剑客awk

awk-命令讲解&#xff1a; awk-命令讲解 一、awk&#xff1a;1.定义&#xff1a;2.格式&#xff1a;3.工作过程&#xff1a;4.工作原理&#xff1a;5.常用选项&#xff1a; 二、内置函数&#xff1a;1.getline的工作过程&#xff1a;2.打印&#xff1a;3.文件内容匹配过滤打印…

软考A计划-系统架构师-学习笔记-第四弹

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff…

信道编码的基本概念

本专栏包含信息论与编码的核心知识&#xff0c;按知识点组织&#xff0c;可作为教学或学习的参考。markdown版本已归档至【Github仓库&#xff1a;https://github.com/timerring/information-theory 】或者公众号【AIShareLab】回复 信息论 获取。 文章目录 信道编码信道编码的…

[迁移学习]预训练和微调

一、概述 一般的有监督迁移学习分为以下三种&#xff1a; ①将训练好的模型作为特征抽取模块&#xff08;例如以resnet进行特征提取&#xff09; ②在一个相关的任务中训练后直接后直接使用(例如gpt) ③在训练好的模型基础上进行微调 此外还有无监督学习的方式 zero-shot&#…

jmeter004:察看结果树

元件添加路径&#xff1a;线程组>监听器>察看结果树 取样器结果&#xff1a; ps&#xff1a;取样器是可以显示变量所对应的值的 Thread Name&#xff1a;线程组名称 Sample Start&#xff1a;运行的开始时间 Load time&#xff1a;加载的时间、持续的时间 Connect Time&a…

从零玩转系列之微信支付开篇

一、前言 halo各位大佬很久没更新了最近在搞微信支付,因商户号审核了我半个月和小程序认证也找了资料并且将商户号和小程序进行关联,至此微信支付Native支付完成.此篇文章过长我将分几个阶段的文章发布(项目源码都有,小程序和PC端) 二、演示 微信支付Native案例 微信支付JSAPI案…

【MySQL】数据表的基本操作

目录 1. 创建表 2. 创建表案例 2.1 创建一个users表 2.2 查看表结构 2.3 修改表 3. 删除表 MySQL&#x1f337; 1. 创建表 语法&#xff1a; CREATE TABLE table_name (field1 datatype,field2 datatype,field3 datatype ) character set 字符集 collate 校验规则 engine 存储…

Blogger空闲短域名搜索代码

Blogger是一个由Google提供的&#xff08;收购的公司&#xff09;免费博客平台&#xff0c;旨在使个人博客创建变得容易。用户可以使用Blogger创建自己的博客并将其托管在Google的服务器上。它不需要任何费用&#xff0c;并提供简单易用的编辑器和主题来帮助用户轻松地创建博客…

网络安全学术顶会——SP 2023 议题清单、摘要与总结(下)

注&#xff1a;本文由ChatGPT与Claude联合生成 121、QueryX: Symbolic Query on Decompiled Code for Finding Bugs in COTS Binaries 可扩展的静态检查工具&#xff0c;如Sys和CodeQL&#xff0c;成功地发现了源代码中的错误。这些工具允许分析人员编写应用程序特定的规则&…

虚拟机角度下的线程

虚拟机角度下的线程 jvm与线程 一个 Java 应用程序通常只包含一个 JVM 进程&#xff08;Java Virtual Machine&#xff0c;Java虚拟机&#xff09;&#xff0c;但在某些情况下可能会有多个 JVM 进程。 一个 Java 应用通常是一个进程&#xff0c;这个进程就是jvm&#xff0c;编…

从Cookie到Session: Servlet API中的会话管理详解

文章目录 一. Cookie与Session1. Cookie与Session2. Servlet会话管理操作 二. 登录逻辑的实现 一. Cookie与Session 1. Cookie与Session 首先, 在学习过 HTTP 协议的基础上, 我们需要知道 Cookie 是 HTTP 请求报头中的一个关键字段, 本质上是浏览器在本地存储数据的一种机制,…

基本类型转换和引用类型转换

文章目录 前言基本类型转换自动数据类型转换强制数据类型转换 引用数据类型转换向上转型向下转型 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; Java 中的类型转换可以分为基本类型转换和引用类型转换两种。 基本类型转换指的是将一种基本数据类型转换…

Koa学习3:用户添加、错误处理

模型 在src目录下创建model目录&#xff0c;用来存放模型 创建用户模型 user.model.js 注意&#xff1a; UUID类型是无法自增的&#xff0c;将id设置为UUID类型时只需要为其指定默认值即可 // 数据类型 const { DataTypes } require(sequelize); // 导入已经连接了数据库…

集合导题、刷题、考试全套完整流程,专业强大的功能,提高刷题学习效率和企业的培训效率

土著刷题微信小程序v1.15&#xff0c;主要是迭代了考试模块的进阶功能&#xff0c;对考试模块进行了一次升级改造。 由于在v1.15开发期间&#xff0c;收到了违规内容整改的通告&#xff0c;为了遵守相关法律法规&#xff0c;让小程序能够平稳安全地运营下去&#xff0c;我们特此…

我说用count(*)统计行数,面试官让我回去等消息...

前言 1 count&#xff08;*&#xff09;为什么性能差&#xff1f; 2 如何优化count&#xff08;*&#xff09;性能&#xff1f; 2.1 增加redis缓存 2.2 加二级缓存 2.3 多线程执行 2.4 减少join的表 2.5 改成ClickHouse 3 count的各种用法性能对比 前言 最近我在公司优…

Consul单机集群

一、准备工作 1、下载consul consul各版本下载地址&#xff0c;点击如下连接前往&#xff1a; Consul Versions | HashiCorp Releases 本案例使用版本&#xff1a;Consul v1.15.0 &#xff1b;下载的文件解压皆可&#xff0c;consul为可执行文件。 2、创建目录&#xff1a…

移动安全app渗透测试之渗透流程、方案及测试要点讲解

被产品经理分到了个app测试的活&#xff0c;&#xff08;话说为啥是产品经理给派活&#xff0c;我不是归技术总监管么&#xff09;&#xff0c;包含安卓端的和ios端的&#xff0c;有点懵逼&#xff0c;说好的web渗透测试和服务器端渗透测试呢&#xff0c;虽然懵逼&#xff0c;不…

【V4L2】v4l2框架分析之video_device

文章目录 &#x1f53a;一、video_device分析&#xff08;1-1&#xff09;struct video_device结构&#xff08;1-2&#xff09;struct v4l2_ioctl_ops结构&#xff08;1-3&#xff09;v4l2_file_operations结构 &#x1f53a;二、注册video设备&#x1f53a;三、卸载清除video…