单源最短路径 洛谷【P4779】

题目描述

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

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

输入格式

第一行为三个正整数 n,m,sn,m,s。 第二行起 mm 行,每行三个非负整数 ui,vi,wiui​,vi​,wi​,表示从 uiui​ 到 vivi​ 有一条权值为 wiwi​ 的有向边。

输出格式

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

输入输出样例

输入 #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≤1051≤n≤105;

1≤m≤2×1051≤m≤2×105;

s=1s=1;

1≤ui,vi≤n1≤ui​,vi​≤n;

0≤wi≤1090≤wi​≤109, 

0≤∑wi≤1090≤∑wi​≤109。

代码解答: 

cpp
#include <iostream>
#include <queue>
#include <cstdio>
#include <algorithm>
#include <limits>using namespace std;// 常量定义
const int INF = numeric_limits<int>::max();
const int MAX_NODES = 100010;    // 最大节点数
const int MAX_EDGES = 500010;    // 最大边数// 边的结构体
struct Edge {int destination, weight, next; // 目的节点、边的权重、下一条边的索引
};// 邻接表
Edge edges[MAX_EDGES];
int head[MAX_NODES], edgeCount = 0; // head 数组表示每个节点的邻接边链表,edgeCount 记录总边数// 向邻接表中添加一条边
void addEdge(int from, int to, int weight) {edges[++edgeCount].destination = to;edges[edgeCount].weight = weight;edges[edgeCount].next = head[from];head[from] = edgeCount;
}int numNodes, numEdges, source;
int distances[MAX_NODES]; // 保存从源点到每个节点的最短距离// 节点结构体,用于优先队列中的元素
struct Node {int id, distance;bool operator < (const Node &other) const {return distance > other.distance; // 小顶堆(距离小的优先)}
};// Dijkstra 算法
void dijkstra() {fill(distances, distances + numNodes + 1, INF); // 初始化所有距离为 INFdistances[source] = 0; // 源点到自己的距离为 0priority_queue<Node> pq; // 优先队列(最小堆)pq.push({source, 0});while (!pq.empty()) {Node current = pq.top();pq.pop();int u = current.id;int currentDistance = current.distance;if (currentDistance != distances[u]) continue; // 如果当前距离已经不是最短距离,则跳过// 遍历所有邻接边for (int i = head[u]; i; i = edges[i].next) {int v = edges[i].destination;int weight = edges[i].weight;// 如果通过 u 到达 v 的距离更短,则更新并加入优先队列if (distances[u] + weight < distances[v]) {distances[v] = distances[u] + weight;pq.push({v, distances[v]});}}}
}int main() {int from, to, weight;scanf("%d%d%d", &numNodes, &numEdges, &source); // 读取节点数、边数和源点for (int i = 1; i <= numEdges; i++) {scanf("%d%d%d", &from, &to, &weight); // 读取每条边的信息addEdge(from, to, weight);}dijkstra(); // 执行 Dijkstra 算法for (int i = 1; i <= numNodes; i++) {if (distances[i] == INF) {printf("INF ");} else {printf("%d ", distances[i]);}}return 0;
}

局部代码解析: 

 const int INF = numeric_limits<int>::max():

在 C++ 中,const int INF = numeric_limits<int>::max(); 是用来定义一个表示“无穷大”的常量。这个常量通常用于图算法中,作为一种便捷的方式来表示一个节点到其他节点的距离是不可达的。下面是详细的解释:

numeric_limits<int>::max()

  • numeric_limits<int> 是 C++ 标准库中的一个模板类,用于提供有关 int 类型的信息。
  • max() 是 numeric_limits 类的一个静态成员函数,它返回该类型可以表示的最大值。

例如,对于 int 类型,numeric_limits<int>::max() 通常返回 2147483647(在大多数系统上),这表示 int 类型能够存储的最大整数值。

 

bool operator < (const Node &other) const:

在 C++ 中,operator< 的重载用于定义两个对象在特定条件下的大小关系。对于 Node 结构体,重载 < 运算符通常是为了在容器中如优先队列(std::priority_queue)或者集合(std::set)中确定元素的排序方式。

让我们详细分析 bool operator < (const Node &other) const 的重载在 Node 结构体中的用途:

cpp
struct Node {int id, distance;bool operator < (const Node &other) const {return distance > other.distance; // 实现小顶堆的排序}
};
 作用
  1. 定义排序规则

    • 这个重载的 < 运算符定义了两个 Node 对象的比较方式。特别地,这个实现会影响数据结构如何对这些 Node 对象进行排序。
    • 在标准的 std::priority_queue 中,元素是根据优先级(或排序标准)进行排列的。默认情况下,std::priority_queue 实现为大顶堆(即最大优先队列),即最大元素优先出队列。
  2. 小顶堆实现

    • 在 Node 结构体中,bool operator < (const Node &other) const { return distance > other.distance; } 实现了一个小顶堆(即最小优先队列)的排序规则。
    • 具体来说,这行代码表示如果当前 Node 的 distance 大于 other 的 distance,那么当前 Node 被认为不小于 other。因此,具有较小 distance 的 Node 会有更高的优先级,被优先处理。
为什么要这么写?
  • 优先队列的要求

    • std::priority_queue 默认是大顶堆。如果希望实现小顶堆,可以通过重载 < 运算符来改变排序规则。这是因为 std::priority_queue 是基于堆实现的,其中堆的性质是通过比较操作定义的。
  • 小顶堆的实现

    • 小顶堆中的根节点是所有节点中 distance 最小的节点。为了让小顶堆的性质成立,较小的 distance 应该排在前面(即更高的优先级)。因此,通过将 distance > other.distance 用于比较,确保了距离较小的节点会优先于距离较大的节点。

实际应用

在实际应用中,例如 Dijkstra 算法中使用优先队列来处理图的节点时,节点的距离是算法的关键部分。通过使用小顶堆,可以确保每次从队列中取出的节点都是当前距离最小的节点,这样算法能正确地找到最短路径。

 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript 循环控制语句-break和continue

break循环 首先i0&#xff0c;判断i是否<5,满足条件&#xff0c;判断i是否等于3&#xff0c;i不等于3&#xff0c;输出i0&#xff0c;i的值加1&#xff0c;判断i是否<5&#xff0c;判断i是否等于3&#xff0c;i不等于3&#xff0c;输出i1&#xff0c;i的值加1&#xff0c…

高精度加法,减法,乘法,除法

加法&#xff1a; 大整数该如何储存&#xff1f; 用数组储存&#xff1a; 把个位放在数下标为0的位置&#xff0c;十位放在数组下标为1的位置&#xff08;也就是高位放在数组的后面&#xff09; 因为这样&#xff0c;如果需要增加一位最高位&#xff0c;那我们就可以直接在…

前端基础 | HTML基础:HTML结构,HTML常见标签

文章目录 HTML1、HTML结构1.1HTML标签1.1.1标签1.1.2标签含义 1.2HTML文件基本结构1.3标签层次结构1.4 快速生成代码框架 2、HTML常见标签2.1注释标签2.2标题标签&#xff1a;h1–h62.3段落标签&#xff1a;p2.4 换行标签&#xff1a;br2.5格式化标签2.6 图片标签&#xff1a;i…

git submodule子模块的使用

子模块的使用 添加子模块 添加子模块 git submodule add <子仓库URL> <子仓库路径> 例子&#xff1a; git submodule add http://192.168.100.181/guideir/poco.git 3rdparty/poco 若子模块存在好几个分支&#xff0c;可以在添加子模块时&#xff0c;指定分支 g…

两个月冲刺软考——访问位与修改位的题型(淘汰哪一页);内聚的类型;关于码制的知识点;地址映射的相关内容

1.访问位与修改位的题型(淘汰哪一页) 访问位&#xff1a;为1时表示在内存期间被访问过&#xff0c;为0时表示未被访问&#xff1b;修改位&#xff1a;为1时表示该页面自从被装入内存后被修改过&#xff0c;为0时表示未修改过。 置换页面时&#xff0c;最先置换访问位和修改位为…

mac安装spark

参考&#xff1a;在Mac上安装Spark apache-spark-3.5.1_mac安装spark-CSDN博客 几个需要用到的路径&#xff1a; hadoop的bin目录&#xff1a;/opt/homebrew/Cellar/hadoop/3.4.0/bin spark的conf目录/opt/homebrew/Cellar/apache-spark/3.5.2/libexec/conf spark的bin目录&am…

iOS——retain和release底层原理

retain实现原理 retain的源码&#xff1a; //使用此方法等价于使用[this retain] inline id objc_object::retain() {//确保对象不是tagged pointerASSERT(!isTaggedPointer());return rootRetain(false, RRVariant::FastOrMsgSend); }ALWAYS_INLINE id objc_object::rootR…

VR虚拟展厅的应用场景有哪些?

虚拟展厅作为一种利用虚拟现实技术构建的三维展示空间&#xff0c;其应用场景广泛且多样。视创云展为企业虚拟展厅搭建提供技术支持。以下是一些主要的应用场景&#xff1a; 1. 博物馆和艺术展览 文物保护与展示&#xff1a; 在博物馆中&#xff0c;为了保护珍贵的文物和艺术…

数据结构与算法学习day20-二叉树的最大深度、最小深度、完全二叉树的节点个数、平衡二叉树、二叉树所有路径

一、二叉树的最大深度 1.题目 104. 二叉树的最大深度 - 力扣&#xff08;LeetCode&#xff09; 2.思路 2.1递归法 二叉树节点的深度&#xff1a;指从根节点到该节点的最长简单路径边的条数或者节点数&#xff08;取决于深度从0开始还是从1开始&#xff09;二叉树节点的高度…

【Python 学习】Pandas基础与应用(1)

题目 1 Pandas 简介1.1 主要特征1.2 Pandas 安装 2 Pandas中的数据结构2.1 Series 数据结构和操作2.1.1 Series的数据结构2.1.2 Seres的操作 2.2 DataFrame 数据结构和操作2.2.1 DataFrame 数据结构2.2.2 Dataframe 操作2.2.3 DateFrame 的特殊操作 2.3 Series 和 DataFrame 的…

Linux——网络基础Socket编程

目录 一计算机网络背景 二协议 1初始协议 1.1协议分层 1.2OSI七层模型 1.3TCP/IP五层模型 2再始协议 2.1为什么要有TCP/IP协议 2.2TCP/IP与OS的关系 2.3所以什么是协议 三网络传输基本流程 1局域网&#xff08;以太网&#xff09;通信原理 1.1认识mac地址 2同…

【牛站 / USACO2007】

题目 思路 离散化&#xff08;降低空间复杂度&#xff09; 点的编号 ∈ [ 1 , 1000 ] &#xff0c;但是点的个数最多为 2 ⋅ T ∈ [ 4 , 200 ] 点的编号 \in [1, 1000]&#xff0c;但是点的个数最多为 2 \cdot T \in[4, 200] 点的编号∈[1,1000]&#xff0c;但是点的个数最多为…

python文件自动化(4)

接上节课内容&#xff0c;在开始正式移动文件到目标文件夹之前&#xff0c;我们需要再思考一个问题。在代码运行之前&#xff0c;阿文的下载文件夹里已经存在一些分类文件夹了&#xff0c;比如图例中“PDF文件”这个文件夹就是已经存在的。这样的话&#xff0c;在程序运行时&am…

电脑硬盘数据丢失了怎么恢复?简单实用的硬盘数据找回的方法

我们的电脑使用硬盘作为存储设备来保存数据&#xff0c;硬盘里的数据是存储在扇区上&#xff0c;这些存储数据的单元则位于表面有磁性材料的旋转的盘片上。硬盘内部的磁头悬浮于高速旋转的盘片上&#xff0c;用于读写和检索数据。 假如我们使用电脑时不小心删除了某个文件&…

【B题第二套完整论文已出】2024数模国赛B题第二套完整论文+可运行代码参考(无偿分享)

2024数模国赛B题完整论文 摘要&#xff1a; 随着电子产品制造业的快速发展&#xff0c;质量控制与成本优化问题成为生产过程中亟待解决的核心挑战。为应对生产环节中的质量不确定性及成本控制需求&#xff0c;本文结合抽样检测理论和成本效益分析&#xff0c;通过构建数学模型…

ELK笔记

要搞成这样就需要钱来买服务器 开发人员一般不会给服务器权限&#xff0c;不能到服务器上直接看日志&#xff0c;所以通过ELK看日志。不让开发登录服务器。即使你查出来是开发的问题&#xff0c;费时间&#xff0c;而且影响了业务了&#xff0c;就是运维的问题 开发也不能登录…

2024国赛数学建模C题论文:基于优化模型的农作物的种植策略

大家可以查看一下35页&#xff0c;包含结构完整&#xff0c;数据完整的C题论文&#xff0c;完整论文见文末名片 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 添加图片注释&#xf…

Computer Exercise

每日一练 单选题 &#xff08;     D     &#xff09; 的作用是在外界中断供电的情况下&#xff0c;及时给计算机等设备供电。 A.WPS     B.USB     C.UBS     D.UPS&#xff08;    B     &#xff09;广泛应用于精密仪器、医疗设备等对电流稳定性要求较高的场…

Unity之获取Avpro视频画面并在本地创建缩略图

一、效果 获取StreamingAssets文件夹下的所有视频&#xff08;包含其子文件夹&#xff09;&#xff0c;获取指定时间的视频画面&#xff0c;然后将图片保存到本地磁盘中。 二、关于Avpro的事件监听 当指定视频时间进度时会触发FinishedSeeking&#xff0c;代表加载完成这时我们…

fpga系列 HDL:Relu激活函数实现与仿真

代码实现对OUTPUT_NODES个32位浮点数进行RELU操作。32位浮点数的二进制表示遵循 IEEE 754 标准&#xff0c;通常称为单精度浮点数。这个标准定义了浮点数的表示方法&#xff0c;具体分为三个部分&#xff1a; 符号位 (1 bit): 用于表示浮点数的正负。&#xff08; 0 表示正数&a…