当前位置: 首页 > news >正文

题解:洛谷 P4779 【模板】单源最短路径(标准版)

【题目来源】

洛谷:P4779 【模板】单源最短路径(标准版) - 洛谷

【题目描述】

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

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

【输入】

第一行为三个正整数 \(n,m,s\)。 第二行起 \(m\) 行,每行三个非负整数 \(u_i,v_i,w_i\),表示从 \(u_i\)\(v_i\) 有一条权值为 \(w_i\) 的有向边。

【输出】

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

【输入样例】

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

【输出样例】

0 2 4 3

【算法标签】

《洛谷 P4779 单源最短路径(标准版)》 #图论# #优先队列# #最短路# #模板题#

【代码详解】

//堆优化Dijkstra 
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;const int N = 100010;  // 最大顶点数
int n, m, s;           // n: 顶点数, m: 边数, s: 起点
int a, b, c;           // 临时变量: 起点, 终点, 权重struct edge
{int v;  // 邻接顶点int w;  // 边权重
};
vector<edge> e[N];  // 邻接表存储图
int d[N];           // 最短距离数组
int vis[N];         // 标记顶点是否已出队/*** Dijkstra算法实现(堆优化)* 求从起点s到所有其他顶点的最短路径* 注意:这里使用大根堆,通过存入负距离实现小根堆功能* @param s 起始顶点*/
void dijkstra(int s)
{// 初始化距离数组memset(d, 0x3f, sizeof d);  // 初始化为无穷大d[s] = 0;                     // 起点到自身距离为0// 使用大根堆存储(-距离, 顶点)对// 通过存储负距离,模拟小根堆的效果priority_queue<pair<int, int>> q;  // 默认是大根堆// 起点入队q.push({0, s});  // 距离为0,顶点为s// 主循环while (q.size()){// 取出堆顶元素auto t = q.top();q.pop();int u = t.second;  // 获取顶点编号// 如果顶点已出队,跳过if (vis[u]){continue;  // 再出队跳过}vis[u] = 1;  // 标记u已出队// 遍历u的所有邻接边for (auto ed : e[u]){int v = ed.v;  // 邻接顶点int w = ed.w;  // 边权重// 松弛操作if (d[v] > d[u] + w){d[v] = d[u] + w;  // 更新最短距离// 入队,存储负距离以实现小根堆q.push({-d[v], v});  // 大根堆,负数使距离小的在堆顶}}}
}int main()
{// 输入顶点数、边数、起点cin >> n >> m >> s;// 构建邻接表for (int i = 0; i < m; i++){cin >> a >> b >> c;e[a].push_back({b, c});  // 添加有向边}// 执行Dijkstra算法dijkstra(s);// 输出结果for (int i = 1; i <= n; i++){printf("%d ", d[i]);}return 0;
}
// 使用acwing模板二刷
#include <bits/stdc++.h>
using namespace std;const int N = 100005;   // 最大顶点数
const int M = 200005;   // 最大边数int n, m, s;            // n: 顶点数, m: 边数, s: 起点
int h[N];               // 邻接表头指针
int e[M], ne[M], w[M];  // 链式前向星: 终点, 下一条边, 权重
int idx;                // 边的索引
int dist[N];            // 起点到各点的最短距离
bool st[N];             // 标记顶点是否已确定最短路径typedef pair<int, int> PII;  // 存储(距离, 顶点)
priority_queue<PII, vector<PII>, greater<PII> > heap;  // 小根堆/*** 添加有向边* @param a 起点* @param b 终点* @param c 权重*/
void add(int a, int b, int c)
{e[idx] = b;        // 边指向的顶点w[idx] = c;        // 边的权重ne[idx] = h[a];    // 指向原链表头h[a] = idx++;      // 更新头指针
}/*** 堆优化的Dijkstra算法* 计算从起点s到所有顶点的最短路径* 注意:第22行代码有错误,应为dist[s] = 0* @param s 起始顶点*/
void dijkstra(int s)
{// 初始化所有距离为无穷大memset(dist, 0x3f, sizeof(dist));// 错误:这里应该设置dist[s] = 0,而不是dist[1] = 0dist[1] = 0;  // 错误!应该是dist[s] = 0// 起点入堆heap.push({0, s});while (!heap.empty()){// 取出堆顶(距离最小的顶点)auto t = heap.top();heap.pop();int veid = t.second;     // 顶点编号int distance = t.first;  // 当前距离// 如果顶点已确定最短路径,跳过if (st[veid] == true){continue;}st[veid] = true;  // 标记为已确定// 遍历veid的所有邻接边for (int i = h[veid]; i != -1; i = ne[i]){int j = e[i];  // 邻接顶点// 松弛操作:如果通过veid到j的路径更短if (dist[j] > distance + w[i]){dist[j] = distance + w[i];  // 更新最短距离heap.push({dist[j], j});    // 新距离入堆}}}
}int main()
{// 输入顶点数、边数、起点cin >> n >> m >> s;// 初始化邻接表memset(h, -1, sizeof(h));// 读入边for (int i = 1; i <= m; i++){int a, b, c;cin >> a >> b >> c;add(a, b, c);  // 添加有向边}// 执行Dijkstra算法dijkstra(s);// 输出结果for (int i = 1; i <= n; i++){cout << dist[i] << " ";}cout << endl;return 0;
}

【运行结果】

4 6 1
1 2 2
2 3 2
2 4 1
1 3 5
3 4 3
1 4 4
0 2 4 3
http://www.jsqmd.com/news/394618/

相关文章:

  • 矩阵乘法与同维空间互相转换(以二维为例)
  • 世毫九理论体系·正式总目录
  • 题解:洛谷 P1600 [NOIP 2016 提高组] 天天爱跑步
  • 美团礼品卡回收实用指南解决闲置困扰 - 京顺回收
  • 题解:洛谷 P2052 [NOI2011] 道路修建
  • 题解:洛谷 P1351 [NOIP 2014 提高组] 联合权值
  • 题解:洛谷 P5836 [USACO19DEC] Milk Visits S
  • YOLO26涨点改进 | 全网独家创新、注意力改进篇 | SCI一区 2025 | YOLO26引入MSCA多尺度稀疏交叉聚合,GCBAM分组注意力,助力遥感目标检测、图像分类任务有效涨点
  • 题解:洛谷 P3128 [USACO15DEC] Max Flow P
  • 题解:洛谷 P3379 【模板】最近公共祖先(LCA)
  • 题解:洛谷 P1395 会议
  • Claude Sonnet 4.6发布,操控计算机能力大幅提升,100万token上下文
  • 京东 e 卡闲置别浪费!可可收更安心,这样选最省心 - 可可收
  • 题解:洛谷 P3372 【模板】线段树 1
  • 研磨废水回用厂家怎么挑?2026年攻略来了,实验室废水处理/研磨废水回用(处理)/零排放清洗,研磨废水回用源头厂家找哪家 - 品牌推荐师
  • 题解:洛谷 P1099 [NOIP 2007 提高组] 树网的核
  • 闲置支付宝立减金别浪费!合规回收方法来了,新手也能轻松上手 - 可可收
  • Python3教程梳理
  • 题解:洛谷 P5908 猫猫和企鹅
  • 题解:洛谷 P5677 [GZOI2017] 配对统计
  • 2026沸石转轮一体机企业TOP榜:哪些品牌值得关注?催化燃烧/旋风除尘器/除尘器,沸石转轮制造厂家排行榜单 - 品牌推荐师
  • 瑞祥商联卡闲置不用?这样的合规回收方式,新手也能轻松上手 - 可可收
  • 2026年值得推荐的AVIF转WebP在线工具盘点(支持批量转换)
  • 微信立减金回收技巧:47%闲置率下,5招盘活你的“隐形财富” - 可可收
  • 2026年溴化锂中央空调选购指南:值得关注的公司,溴化锂冷水机组/二手溴化锂中央空调,溴化锂中央空调制造企业有哪些 - 品牌推荐师
  • PAM4相关概念
  • 2026年行业内评价高的调节阀厂商如何选,电液动盲板阀/蝶式止回阀/微阻缓闭止回阀/伸缩蝶阀,调节阀生产厂家哪家权威 - 品牌推荐师
  • 2026年中考体育训练新趋势:智慧体育制造企业深度解析,智能运动手环管理平台/握力测试仪,智慧体育生产厂家哪家好 - 品牌推荐师
  • 闲置分期乐购物额度用不上?教你安全高效回收,不浪费一分额度 - 可可收
  • 题解:洛谷 P1631 序列合并