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

C++练习:图论的两种遍历方式

一、遍历

一提到遍历,我们首先想到的肯定是树的遍历。因为在数据结构中我们是从树引出图的。但图明显比树更常见,更丰富,更多变。所以我们可能会被树的一些知识所固化了思维。比如树的遍历有前、中、后遍历,或者深度优先、广度优先搜索等。但这些都是正向遍历,从一个固定的起点开始,自上而下。可在图中除了正向遍历,你还可能可以逆向遍历。

二、正向和逆向

在图论中,正向遍历和反向遍历指的是根据图的结构(如边的方向)对节点进行访问的两种不同方式。它们主要用于有向图中,因为无向图没有明确的方向性,所以这种区分不那么明显。

正向遍历

  • 定义:按照图中边的方向从一个节点到另一个节点进行遍历。
  • 适用场景:当您需要遵循关系或路径的方向时,例如在一个依赖关系图中,您可能希望从先决条件开始,然后按顺序处理每个后续任务。
  • 算法示例:深度优先搜索(DFS)、广度优先搜索(BFS),以及其他基于图的算法,通常默认是正向遍历。

反向遍历

  • 定义:与边的方向相反的方式进行遍历,即逆着箭头方向。
  • 适用场景:反向遍历对于解决某些特定问题非常有用,比如寻找哪些节点可以到达给定的终点,或者在拓扑排序中,如果需要找出所有依赖于某个节点的其他节点。
  • 算法示例:Kosaraju算法用于查找强连通分量,其中一个步骤就是反向遍历图。

选择依据

  • 使用正向遍历时:如果您关心的是起点到终点的路径,或者是想了解一个节点能直接或间接到达哪些其他节点,那么正向遍历通常是合适的选择。
  • 使用反向遍历时:如果您更关注哪些节点可以到达特定的终点,或者是想要分析依赖关系中的上游节点,反向遍历会更加有效。

总之,选择正向还是反向遍历取决于您试图解决的具体问题以及图的结构特点。理解您的需求和图的特点将帮助您决定采用哪种遍历方式。

三 、1376

正向:

class Solution {
    int maxTime = 0;
    void dfs(int root, int allTime, vector<vector<int>> &map, vector<int>& informTime){
        if(map[root].size() == 0) maxTime = max(maxTime, allTime);
        for(auto son : map[root]){
            dfs(son, allTime + informTime[root], map, informTime);
        }
    }

public:
    int numOfMinutes(int n, int headID, vector<int>& manager, vector<int>& informTime) {
        vector<vector<int>> map(n);
        for(int i = 0; i < n; ++ i){
            if(manager[i] == -1) continue;
            map[manager[i]].emplace_back(i);
        }
        dfs(headID, 0, map, informTime);
        return maxTime;
    }
};
逆向:

```cpp
class Solution {
    vector<int> dp;
    void dfs(int i, vector<int> &manager, vector<int>& informTime){
        if(dp[i] != -1) return;
        if(dp[manager[i]] == -1) dfs(manager[i], manager, informTime);
        dp[i] = dp[manager[i]] + informTime[manager[i]];
    }

public:
    int numOfMinutes(int n, int headID, vector<int>& manager, vector<int>& informTime) {
        dp.resize(n, -1);
        dp[headID] = 0;
        int maxTime = 0;
        for(int i = 0; i < n; ++ i){
            dfs(i, manager, informTime);
            maxTime = max(maxTime, dp[i]);
        }
        return maxTime;
    }
};

http://www.kler.cn/a/451079.html

相关文章:

  • 《计算机组成及汇编语言原理》阅读笔记:p86-p115
  • Android--java实现手机亮度控制
  • 什么样的LabVIEW控制算自动控制?
  • Linux服务器端自动挂载存储设备(U盘、移动硬盘)
  • 《三角洲行动》游戏运行时提示“缺失kernel32.dll”:问题解析与解决方案
  • 某科技局国产服务器PVE虚拟化技术文档
  • 无人直播源码
  • 管理面板Ajenti的在Windows10下Ubuntu24.04/Ubuntu22.04里的配置管理
  • Redis的主从集群以及哨兵机制学习总结
  • Google 提供的 Android 端上大模型组件:MediaPipe LLM 介绍
  • 单片机 STM32入门
  • windows C#-对象和集合初始值设定项(中)
  • RustDesk远程及自建服务器搭建教程
  • Java/JDK下载、安装及环境配置超详细教程【Windows10、macOS和Linux图文详解】
  • 国标GB28181设备管理软件EasyGBS:P2P远程访问故障排查指南(设备端)
  • 自然语言处理与知识图谱的融合与应用
  • K8s - openeuler2203SP1安装 K8s + flannel
  • 浅谈 前端验证码那些事
  • STM32 与 AS608 指纹模块的调试与应用
  • keepalived踩坑记录
  • 前端:纯前端快速实现html导出word和pdf
  • 【EthIf-13】EthIfGeneral容器配置-01
  • IDEA使用Alt + Enter快捷键自动接受返回值一直有final修饰的问题处理
  • 重温设计模式--中介者模式
  • 微积分复习笔记 Calculus Volume 2 - 5.1 Sequences
  • Golang并发机制以及它所使⽤的CSP并发模型