惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

小众软件
小众软件
博客园 - Franky
罗磊的独立博客
G
Google Developers Blog
The GitHub Blog
The GitHub Blog
P
Proofpoint News Feed
Recent Announcements
Recent Announcements
V
V2EX
F
Fortinet All Blogs
阮一峰的网络日志
阮一峰的网络日志
Blog — PlanetScale
Blog — PlanetScale
月光博客
月光博客
U
Unit 42
GbyAI
GbyAI
A
About on SuperTechFans
WordPress大学
WordPress大学
Engineering at Meta
Engineering at Meta
雷峰网
雷峰网
Microsoft Azure Blog
Microsoft Azure Blog
Martin Fowler
Martin Fowler
D
DataBreaches.Net
The Cloudflare Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
MongoDB | Blog
MongoDB | Blog

博客园_首页

Plist 二进制格式 Milvus 和 PGVector,哪个更好? OpenClaw 已过时?在 VS Code 中运行 Hermes Agent! 第30篇文章:一个大三计科生的自白 Manim如何在数学公式中完美显示中文? Docker 部署 RocketMQ 5 并发编程核心概念辨析 C#事务处理最佳实践:别再让“主表存了、明细丢了”的破事发生 CLI 是什么?为什么大厂突然集体卷命令行? 【从0到1构建一个ClaudeAgent】协作-自主Agent UIImageView 设置图片不生效的原因排查 最小二乘问题详解20:无先验约束下的增量式SFM自由网平差 痞子衡嵌入式:大话双核i.MXRT1180之XIP应用里借助MU实现可靠Flash IAP的方法 AI Chat 封装, SemanticKerne.AiProvider.Unified 已发布 Windows下右键编辑js文件无法打开记事本——在注册表中使用环境变量 在后台服务中使用 Scoped 服务,为什么总是报错? H200 安装驱动并使用sglang启动模型 wireshark 抓包Trap上报告警内容 我用 AI 辅助开发了一系列小工具(2):图片压缩工具 [A Primer On MC and CC] 2.1 Memory Consistency 1 - 指令重排序和 SC 模型 Oracle数据库SCN推进技术详解与实践指南 玩转控件:封装个带图片的Label控件 Claude Code 4.7 真正该升级的不是模型,而是你的工作流 前端小白一句话,AI 帮我做了个颜值拉满的桌面媒体播放器。当代码不再是门槛,一句话编程就是现实。 5. WorkBuddy: 小龙虾的灵魂三件套,让你的小龙虾不只是工具 SQLite 分片方案实战:三种分片策略的深度对比 告别简陋 UI!一款基于 Fluent Design 和基于 WinUI 的开源免费、现代化的 Avalonia UI 控件库 关于二进制排列组合枚举的总结 AI开发-python-LangGraph框架(3-27-LangGraph从零实现大模型智能决策工作流) ElasticSearch主分片和副本分片概念详解
#题解/P3371 【模板】单源最短路径(弱化版)
hermanO · 2026-04-30 · via 博客园_首页

知识点

dijkstra算法

介绍 :dijkstra算法用于求解有权图求最短路的问题

具体过程

1.将起始点的dis置为0.
2.选择当前未标记的顶点中dis值最小的一个。
3.对该顶点的所有连边依次进行松弛操作。
4.对该点进行标记。
5.重复第(2)步至第(4)步,直到不存在一条边从已标记顶点通往未标记点的连边

还有一点没说

搞清楚邻接表邻接矩阵适用于什么情况

如果不懂连边,松弛操作等名词含义欢迎拜读我的博客点我

解释:dis数组是用于记录到目前为止起点到各顶点的最短路长度

关于dis数组的细节初始化,在初始化的时候先将整个数组设置为inf,inf:表示无穷大,一般开成1e18-1或者1e9-1

题外话

其实这个算法和BFS求无权图最短路的思路差不多,基础不好的就像我一样 有点搞不懂这个dijkstra函数的形参也就是graph数组他其实存的就是比如\(u \to v\) 代价为w,那么就是graph[u].push_back({w,v}),就是存u点到v点的边权(代价),在主函数初始化的时候你可以注意到
当然我这个代码用堆优化了,也就是优先队列,也要搞懂优先队列的作用,总之你一定要知道你现在要干嘛,等下要干嘛,一定要有思路

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

#define int long long 

vector<int>Dijkstra(int start,int n,vector<vector<pair<int,int> > >& graph)
{
    const int INF = INT_MAX ;
    vector<int>dis(n+1,INF) ;
    dis[start] = 0 ;
  //存{距离,节点} 
    priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int> > >q;
    q.push({0,start});
    while(!q.empty())
    {
        int d = q.top().first ;
        int u = q.top().second ;
        q.pop() ;
        if(d > dis[u]) continue ;/*
在堆优化的 Dijkstra 中,我们无法直接更新队列内部某个节点的值。所以,当发现一条更短的路径时,我们并不是“修改”队列里的旧距离,而是直接塞进去一个新的、更短的距离。
这就导致:同一个节点在队列里可能同时存在多份数据。*/
//简单来说,它的核心作用是:跳过那些已经被发现“不是最短”的路径信息
        for(auto & edge : graph[u])
        {
            int v = edge.first ; //目标节点
            int w = edge.second ; //边权
            if(dis[u] + w < dis[v])
            {
                dis[v] = dis[u] + w ;
                q.push({dis[v],v}) ;
            }
        }
    }
    return dis ;
}

signed main()
{
    ios::sync_with_stdio(false),cin.tie(nullptr) ;
    
    int n,m,s;
    cin >> n >> m >> s;
    // 邻接表:graph[u]存储从u出发的所有边 {v, w}
    vector<vector<pair<int, int>>> graph(n + 1);  // 1-indexed
    for(int i = 0;i < m;i++)
    {
        int u,v,w;
        cin >> u >> v >> w ;
        graph[u].push_back({v, w});
    }
    vector<int> dist = Dijkstra(s, n, graph);
    
     for (int i = 1; i <= n; i++) {
        if (dist[i] == INT_MAX) {
            cout << 2147483647 << " ";  // 不能到达
        } else {
            cout << dist[i] << " ";
        }
    }
    cout << endl;

    return 0 ;
}