代码随想录算法训练day64---图论系列8《拓扑排序dijkstra(朴素版)》

news2025/2/26 13:46:50

代码随想录算法训练

—day64

文章目录

  • 代码随想录算法训练
  • 前言
  • 一、53. 117. 软件构建—拓扑排序
  • 二、47. 参加科学大会---dijkstra(朴素版)
  • 总结


前言

今天是算法营的第64天,希望自己能够坚持下来!
今天继续图论part!今日任务:
● 拓扑排序
●dijkstra(朴素版)


一、53. 117. 软件构建—拓扑排序

卡码网题目链接
文章讲解

给出一个 有向图,把这个有向图转成线性的排序 就叫拓扑排序。
适合应用在例如B依赖A,C依赖B,要先有A才能有B,先有B才能有C的依赖关系找出先后顺序的问题。

实现拓扑排序的算法有两种:卡恩算法(BFS)和DFS,一般来说我们只需要掌握 BFS (广度优先搜索)就可以了,清晰易懂。

思路:
在这里插入图片描述
找 入度为 0 的节点,只有入度为0,它才是出发节点。
步骤:
1.找到入度为0 的节点,加入结果集
2.该节点指向的节点入度-1

代码如下:

#include<iostream>
#include<vector>
#include<unordered_map>
#include<queue>
using namespace std;
 
int main() {
    int n, m, s, t;
    cin >> n >> m;
    vector<int> inDegree(n, 0); //记录每个文件的入度
     
    unordered_map<int, vector<int>> umap; //记录文件的依赖 first指向多个second文件
    vector<int> result; //记录结果
     
    while (m--) {
        //s->t 先有s才能有t
        cin >> s >> t;
        inDegree[t]++;
        umap[s].push_back(t); //记录s指向哪些文件
    }
     
    //因为会有不只1个文件入度为0,用队列存放入度为0的文件
    queue<int>que;
    for (int i = 0; i < n; i++) {
        if (inDegree[i] == 0) que.push(i);        
    }
     
    //循环从队列中取出文件处理
    //1.将入度为0的文件加入结果集,2.删掉入度为0的文件
    while (!que.empty()) {
        int cur = que.front();
        que.pop();
        result.push_back(cur);
         
        vector<int> files = umap[cur]; //获取该文件指向的文件
        for (int j = 0; j < files.size(); j++) {
            inDegree[files[j]]--; //cur指向的文件入度-1
            if(inDegree[files[j]] == 0) que.push(files[j]); //新的入度为0的文件加入到队列
        }
    }
     
    //打印结果
    if (result.size() == n) {
        for (int i = 0; i < n - 1; i++) cout << result[i] << " ";
        cout << result[n - 1]; //最后不包含空格,所以分开打印
    } else {
        cout << -1 << endl;
    }
     
    return 0;
}

二、47. 参加科学大会—dijkstra(朴素版)

卡码网题目链接
文章讲解

dijkstra算法:在有权图(权值非负数)中求从起点到其他节点的最短路径算法。
需要注意两点:

  • dijkstra 算法可以同时求 起点到所有节点的最短路径
  • 权值不能为负数

dijkstra和prim算法思路很像,只是dijkstra是求最短路径,minDist数组 用来记录 每一个节点距离源点的最小距离;而prim里的minDist数组是记录每个节点到生成树的最小距离

dijkstra三部曲:
第一步,选源点到哪个节点近且该节点未被访问过
第二步,该最近节点被标记访问过
第三步,更新非访问节点到源点的距离(即更新minDist数组)

为了更好理解,数组下标从1开始,对应节点1,到达节点n对应下标n。
代码如下:

#include<iostream>
#include<vector>
#include<climits>
using namespace std;
 
int main() {
    int n, m, s, e, v;
    cin >> n >> m;
    vector<vector<int>> grid(n + 1, vector<int>(n + 1, INT_MAX));
     
    while (m--) {
        cin >> s >> e >> v;
        grid[s][e]= v;
    }
     
    int start = 1;
    int end = n;
     
    vector<int>minDist(n+1, INT_MAX); //记录从原点到达每个节点的最短路径
    vector<bool>visited(n+1, false);
     
    minDist[start] = 0;
     
     
     //遍历所有节点
    for (int i = 1; i <= n; i++) { 
        int minVal = INT_MAX;
        int cur = 1; //当前节点
         
        //遍历minDist,找出距离原点最近且未访问的节点
        for (int j = 1; j <= n; ++j) {
            if (!visited[j] && minDist[j] < minVal) {
                minVal = minDist[j];
                cur = j;
            }
        }
         
        //标记访问过的节点
        visited[cur] = true;
         
        //更新minDist,这里是判断原点到当前节点+当前节点到下一个节点的距离是否比原来的近
        for (int j = 1; j <= n; j++) {
            if (!visited[j] && grid[cur][j] != INT_MAX && minDist[cur] + grid[cur][j] < minDist[j]) {
                minDist[j] = minDist[cur] + grid[cur][j];
            }
        }
    }
     
    if (minDist[end] == INT_MAX) cout << -1 << endl; //不能到达终点
    else cout << minDist[end] << endl; //到达终点最短路径
     
    return 0;
}

总结

  • 拓扑排序 :
    1.unordered_map<int, vector> umap,存放每个节点指向多个节点
    2.一个vectorinDegrees记录每个节点的入度
    3.遍历inDegrees,用队列queue存放入度为0的节点
    4.遍历queue,将入度为0指向的节点入度-1,并将新的入度为0的节点加入到队列中。

  • dijkstra算法:
    1.vector<vector>grid存放节点间的权值, vectorminDist存放每个节点到源点的最小距离,vectorvisited记录已经被访问的节点
    2.遍历每个节点,遍历minDist,找到离源点最小距离且未访问过的节点
    3.标记成已访问的节点
    4.更新minDist数组

明天继续加油!

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

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

相关文章

2024-2025 学年广东省职业院校技能大赛 “信息安全管理与评估”赛项 技能测试试卷(四)

2024-2025 学年广东省职业院校技能大赛 “信息安全管理与评估”赛项 技能测试试卷&#xff08;四&#xff09; 第一部分&#xff1a;网络平台搭建与设备安全防护任务书第二部分&#xff1a;网络安全事件响应、数字取证调查、应用程序安全任务书任务 1&#xff1a;应急响应&…

单片机的串口(USART)

Tx - 数据的发送引脚&#xff0c;Rx - 数据的接受引脚。 串口的数据帧格式 空闲状态高电平&#xff0c;起始位低电平&#xff0c;数据位有8位校验位&#xff0c;9位校验位&#xff0c;停止位是高电平保持一位或者半位&#xff0c;又或者两位的状态。 8位无校验位传输一个字节…

动态规划(背包问题)--是否逆序使用的问题--二进制拆分的问题

动态规划&#xff08;背包问题&#xff09; 题目链接01背包代码 完全背包问题代码 多重背包问题 I代码 什么时候适用逆序多重背包问题 II&#xff08;超百万级的复杂度&#xff09;代码 关于二进制拆分 题目链接 01背包 代码 #include <iostream> #include <vector&…

Mac 版 本地部署deepseek ➕ RAGflow 知识库搭建流程分享(附问题解决方法)

安装&#xff1a; 1、首先按照此视频的流程一步一步进行安装&#xff1a;(macos版&#xff09;ragflowdeepseek 私域知识库搭建流程分享_哔哩哔哩_bilibili 2、RAGflow 官网文档指南&#xff1a;https://ragflow.io 3、RAGflow 下载地址&#xff1a;https://github.com/infi…

姿态矩阵/旋转矩阵/反对称阵

物理意义&#xff0c;端点矢量角速率叉乘本身向量&#xff1b; 负号是动系b看固定系i是相反的&#xff1b; 一个固定 在惯性导航解算中&#xff0c;旋转矢量的叉乘用于描述姿态矩阵的微分方程。你提到的公式中&#xff0c; ω i b b \boldsymbol{\omega}_{ib}^b \times ωibb…

【大语言模型】【整合版】DeepSeek 模型提示词学习笔记(散装的可以看我之前的学习笔记,这里只是归纳与总结了一下思路,内容和之前发的差不多)

以下是个人笔记的正文内容: 原文在FlowUs知识库上&#xff0c;如下截图。里面内容和这里一样&#xff0c;知识排版好看一点 一、什么是 DeepSeek 1. DeepSeek 简介 DeepSeek 是一家专注于通用人工智能&#xff08;AGI&#xff09;的中国科技公司&#xff0c;主攻大模型研发与…

ollama无法通过IP:11434访问

目录 1.介绍 2.直接在ollama的当前命令窗口中修改&#xff08;法1&#xff09; 3.更改ollama配置文件&#xff08;法2&#xff09; 3.1更新配置 3.2重启服务 1.介绍 ollama下载后默认情况下都是直接在本地的11434端口中运行&#xff0c;绑定到127.0.0.1(localhost)&#x…

Bugku CTF CRYPTO

Bugku CTF CRYPTO 文章目录 Bugku CTF CRYPTO聪明的小羊ok[-<>]散乱的密文.!? 聪明的小羊 描 述: 一只小羊翻过了2个栅栏 fa{fe13f590lg6d46d0d0} 分 析&#xff1a;栅栏密码&#xff0c;分2栏&#xff0c;一个栏里有11个 ①手动解密 f a { f e 1 3 f 5 9 0 l g 6 d 4 …

【洛谷】【ARC100E】Or Plus Max(高维前缀和)

传送门&#xff1a;Or Plus Max 高维前缀和 题目描述 長さ 2N の整数列 A0​, A1​, ..., A2N−1​ があります。&#xff08;添字が 0 から始まることに注意&#xff09; 1 ≤ K ≤ 2N−1 を満たすすべての整数 K について、次の問題を解いてください。 i,j を整数と…

SmolLM2:多阶段训练策略优化和高质量数据集,小型语言模型同样可以实现卓越的性能表现

SmolLM2 采用创新的四阶段训练策略&#xff0c;在仅使用 1.7B 参数的情况下&#xff0c;成功挑战了大型语言模型的性能边界&#xff1a; 在 MMLU-Pro 等测试中超越 Qwen2.5-1.5B 近 6 个百分点数学推理能力&#xff08;GSM8K、MATH&#xff09;优于 Llama3.2-1B在代码生成和文…

《Effective Objective-C》阅读笔记(中)

目录 接口与API设计 用前缀避免命名空间冲突 提供“全能初始化方法” 实现description方法 尽量使用不可变对象 使用清晰而协调的命名方式 方法命名 ​编辑类与协议命名 为私有方法名加前缀 理解OC错误模型 理解NSCopying协议 协议与分类 通过委托与数据源协议进行…

Hbase客户端API——语句大全

目录 创建表&#xff1a; 插入数据&#xff1a; 删除数据&#xff1a; 修改数据&#xff1a; 查询数据&#xff1a;Get 查询数据&#xff1a;Scan 查询数据&#xff1a;过滤查询 创建表&#xff1a; 检验&#xff1a; 插入数据&#xff1a; 验证 一次多条数据插入 验证&…

MQ(Message Queue)

目录 MQ(Message Queue)基本概念 为什么要使用消息队列&#xff1f; 使用消息队列有什么缺点&#xff1f; 如何保证消息不丢失?(如何保证消息的可靠性传输?/如何处理消息丢失的问题?) 通用的MQ场景&#xff1a; RabbitMQ如何保证消息不丢失&#xff1f; 生产者丢数据…

计算机网络————(三)

前文二 前文一 Websocket协议 是一种存在TCP协议之上的协议 当客户端需要了解服务器是否更新就需要不断给客户端发送请求询问是否更新&#xff0c;这行会造成服务端压力很大 而Websocket相当于服务器一旦更新了就会给客户端发送消息表明自己更新了&#xff0c;类似客户端订阅…

【音视频】音视频录制、播放原理

一、音视频录制原理 通常&#xff0c;音视频录制的步骤如下图所示&#xff1a; 我们分别从音频和视频开始采样&#xff0c;通过麦克风和摄像头来接受我们的音频信息和图像信息&#xff0c;这通常是同时进行的&#xff0c;不过&#xff0c;通常视频的采集会比音频的采集慢&…

deepseek 导出导入模型(docker)

前言 实现导出导入deepseek 模型。deepseek 安装docker下参考 docker 导出模型 实际生产环境建议使用docker-compose.yml进行布局&#xff0c;然后持久化ollama模型数据到本地参考 echo "start ollama" docker start ollama#压缩容器内文件夹&#xff0c;然后拷贝…

基于Redis 的分布式 session 图解

Redis 分布式 Session 工作原理 1. 传统 Session 的问题 在传统单服务器环境中&#xff0c;HTTP Session 存储在应用服务器的内存中。这在分布式系统中会导致问题&#xff1a; 用户的请求可能被分发到不同服务器&#xff0c;导致会话不一致服务器宕机会导致会话丢失需要依赖…

DeepSeek-R1本地部署保姆级教程

一、DeepSeek-R1本地部署配置要求 &#xff08;一&#xff09;轻量级模型 ▌DeepSeek-R1-1.5B 内存容量&#xff1a;≥8GB 显卡需求&#xff1a;支持CPU推理&#xff08;无需独立GPU&#xff09; 适用场景&#xff1a;本地环境验证测试/Ollama集成调试 &#xff08;二&a…

【deepseek】本地部署+webui访问

背景 最近deepseek很火&#xff0c;但是官网的老是被限流使用&#xff0c;还有就是自己也想着玩一玩&#xff0c;于是准备在自己电脑跑一个 直接附上结果地址mydeepseek 准备工作 windows和linux都可 我这里选择linux&#xff0c;ubuntu系统 安装ollama 看下图&#xff0…

博客系统笔记总结 2( Linux 相关)

Linux 基本使用和程序部署 基本命令 文件操作 显示当前目录下的文件 ls&#xff1a;显示当前目录下的文件 ll&#xff1a;以列表的形式展示&#xff0c;包括隐藏文件 进入目录 && 显示当前路径 cd&#xff1a;进入目录&#xff08;后面跟相对路径或者绝对路径&…