相关笔记

概览

全章围绕基本图算法展开,系统介绍图的表示方法和两大图遍历策略(BFS 和 DFS),以及它们在拓扑排序和强连通分量分解中的应用。章节从图的两种标准表示出发(20.1),依次介绍广度优先搜索(20.2)和深度优先搜索(20.3)两种遍历算法,然后利用 DFS 的完成时间性质解决 DAG 上的拓扑排序问题(20.4),最后通过两次 DFS + 转置图实现有向图的强连通分量分解(20.5)。全章的核心主线是 DFS 的完成时间性质——它不仅是拓扑排序的基础,也是 SCC 分解的关键工具。


知识结构总览

flowchart TD
    A["第20章 基本图算法"] --> B["20.1 图的表示"]
    A --> C["20.2 广度优先搜索 BFS"]
    A --> D["20.3 深度优先搜索 DFS"]
    A --> E["20.4 拓扑排序"]
    A --> F["20.5 强连通分量 SCC"]

    B --> B1["邻接表: O(V+E) 空间"]
    B --> B2["邻接矩阵: O(V²) 空间"]
    B --> B3["两种表示的选择依据"]

    C --> C1["逐层扩展策略"]
    C --> C2["最短路径性质 (无权图)"]
    C --> C3["BFS 树 + 前驱数组"]
    C --> C4["定理20.1: BFS 正确性"]

    D --> D1["深度优先探索策略"]
    D --> D2["四种边分类: 树边/前向/后向/交叉"]
    D --> D3["发现时间 d 与完成时间 f"]
    D --> D4["括号结构定理"]
    D --> D5["白色路径定理"]

    E --> E1["DAG 定义"]
    E --> E2["TOPOLOGICAL-SORT 算法"]
    E --> E3["定理20.6: 正确性"]
    E --> E4["引理20.7: DAG ⟺ 无后向边"]
    E --> E5["Kahn 算法 (入度法)"]

    F --> F1["SCC 定义"]
    F --> F2["Kosaraju 算法: 两次 DFS"]
    F --> F3["分量图 G^SCC 是 DAG"]
    F --> F4["定理20.9: 正确性"]
    F --> F5["引理20.10~20.14: 证明链"]

    D --> E
    D --> F
    E --> F

核心概念回顾

图的两种表示对比

比较维度邻接表(Adjacency List)邻接矩阵(Adjacency Matrix)
空间
检查边 是否存在
枚举所有邻接顶点
添加边
删除边
适合的图稀疏图(稠密图(
自环/平行边可自然支持需额外处理
加权图存储权重在链表节点中存储权重在矩阵元素中

表示选择的经验法则

(稀疏图)时,邻接表空间 远优于邻接矩阵 (稠密图)时,两者空间相当,邻接矩阵的 边查询更优。实际工程中,大多数图是稀疏的(社交网络、Web 图、道路网),因此邻接表更为常用。

BFS vs DFS 对比

比较维度BFS(广度优先搜索)DFS(深度优先搜索)
核心策略逐层扩展(队列)深入探索(栈/递归)
数据结构队列(FIFO)栈(LIFO)/ 递归调用栈
时间复杂度
空间复杂度(队列 + 颜色 + 距离 + 前驱)(递归栈 + 颜色 + 时间戳 + 前驱)
最短路径保证找到无权图最短路径不保证
边分类树边、非树边(不细分)树边、前向边、后向边、交叉边
发现/完成时间无(只有距离)
适用场景最短路径、层序遍历拓扑排序、SCC、环检测、连通性
非递归实现自然(队列)需要显式栈
连通分量可检测可检测
典型应用Web 爬虫、社交网络最短路径编译器分析、游戏 AI、迷宫生成

五种算法复杂度汇总

算法时间复杂度空间复杂度适用图类型核心功能
BFS无向/有向最短路径(无权)、层序遍历
DFS无向/有向连通性、环检测、边分类
拓扑排序(DFS)有向无环图线性排列
拓扑排序(Kahn)有向无环图线性排列 + 回路检测
Kosaraju SCC有向图强连通分量分解

五节内容对比

维度20.1 图的表示20.2 广度优先搜索20.3 深度优先搜索20.4 拓扑排序20.5 强连通分量
核心主题图的数据结构基础层序遍历策略深度探索策略DAG 的线性排列有向图的分解
关键概念邻接表、邻接矩阵距离、前驱、BFS 树发现/完成时间、四种边、括号结构DAG、完成时间递减SCC、转置图、分量图
关键定理定理20.1(BFS 正确性)白色路径定理、括号结构定理20.6(拓扑排序正确性)、引理20.7定理20.9(SCC 正确性)、引理20.10~20.14
核心算法BFSDFSTOPOLOGICAL-SORTSTRONGLY-CONNECTED-COMPONENTS
时间复杂度
数据结构数组 + 链表队列栈/递归DFS + 链表DFS + 转置图
难度⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
设计思想表示选择决定效率”波纹扩散""一条路走到黑”完成时间蕴含依赖序两次 DFS + 图的对称性
与其他节关系全章基础DFS 的”兄弟”拓扑排序和 SCC 的基础依赖 DFS 完成时间依赖 DFS + 拓扑排序思想

关键定理索引

定理/引理结论所在节笔记
定理20.1BFS 正确性:BFS 正确计算从源点 到所有可达顶点的最短路径距离20.2 广度优先搜索
引理(BFS 最短路径)对每条边 20.2 广度优先搜索
白色路径定理 在 DFS 树中的后代当且仅当在发现 时存在一条从 的全白色路径20.3 深度优先搜索
括号结构定理三个等价条件刻画 DFS 树中的祖先-后代关系20.3 深度优先搜索
边分类定理DFS 将有向图的边分为四类:树边、前向边、后向边、交叉边20.3 深度优先搜索
引理20.7有向图是 DAG 当且仅当 DFS 不产生后向边20.4 拓扑排序
定理20.6如果 是 DAG,则 TOPOLOGICAL-SORT 产生拓扑排序20.4 拓扑排序
引理20.10若 SCC 有边指向 ,则 20.5 强连通分量
引理20.12 的 DFS 树恰好包含一个 SCC 的所有顶点20.5 强连通分量
定理20.9Kosaraju 算法正确计算所有 SCC20.5 强连通分量

易混淆点汇总

BFS vs DFS

维度BFSDFS
探索顺序”先近后远”(按距离递增)“先深后广”(沿一条路径深入)
最短路径保证(无权图)不保证
实现方式迭代(队列)递归或迭代(栈)
栈溢出风险递归实现可能栈溢出
适用场景找最短路径、层序遍历找所有路径、检测环、拓扑排序

拓扑排序 vs SCC

维度拓扑排序强连通分量
适用图类型DAG(有向无环图)一般有向图
输出顶点的线性排列顶点的分组(等价类)
核心操作一次 DFS + 按完成时间排列两次 DFS + 转置图
回路处理无回路时才有解有回路时 SCC 包含多个顶点
关系分量图的拓扑排序先求 SCC,再对分量图做拓扑排序

DAG vs 一般有向图

维度DAG一般有向图
有向回路可能有
拓扑排序存在可能不存在
最长路径 可解NP 难
DFS 边分类无后向边可能有后向边
分量图就是自身(每个顶点是一个 SCC)可能有多顶点 SCC

邻接表 vs 邻接矩阵

维度邻接表邻接矩阵
空间
边查询
邻接枚举
适合图类型稀疏图稠密图
BFS/DFS 复杂度
实际使用更常见特定场景

树边 vs 前向边 vs 后向边 vs 交叉边

边类型定义出现条件
树边DFS 发现新顶点时经过的边所有图
前向边从祖先指向非直接后代的后代有向图
后向边从后代指向祖先有向图(DAG 中不存在)
交叉边其他所有边(非树边、非前向、非后向)有向图

后向边是有向回路的充要条件

在有向图中,DFS 产生后向边当且仅当图包含有向回路。 这是引理20.7的核心结论,也是判断 DAG 的线性时间方法。注意:无向图中不存在前向边和交叉边的区分——无向图的 DFS 只有树边和”后向边”(实际是连接到已访问节点的边)。


补充理解(跨节综合视角)

图算法的演进脉络

本章的五节内容形成了一条清晰的逻辑链:

基础层(20.1):图的表示。 邻接表和邻接矩阵是所有图算法的基石。表示的选择直接影响算法的效率——邻接表使 BFS 和 DFS 达到 ,而邻接矩阵下它们退化为

遍历层(20.2-20.3):BFS 和 DFS。 两种遍历策略是图算法的”元操作”。BFS 的核心贡献是最短路径性质(无权图),DFS 的核心贡献是完成时间性质和边分类。DFS 的完成时间 是本章后续所有高级应用的基础。

应用层(20.4-20.5):拓扑排序和 SCC。 拓扑排序直接利用 DFS 的完成时间递减性质;SCC 算法则进一步利用完成时间 + 转置图的对称性。两者都建立在 DFS 的理论框架之上。

DFS 完成时间:贯穿全章的核心线索

DFS 的完成时间 是本章最重要的概念。它蕴含了丰富的结构信息:

  • 意味着 的”探索范围”包含 的后代或在 之前完成)
  • 按完成时间递减排列得到拓扑排序(20.4节)
  • 完成时间最大的顶点位于源 SCC 中(20.5节引理20.10)
  • SCC 间的完成时间关系决定了 Kosaraju 算法的处理顺序

理解了完成时间的含义,就理解了本章后半部分的核心。

工程选型指南

场景推荐算法理由
无权图最短路径BFS,保证最短路径
检测图中是否有环DFS检查是否有后向边(有向)或回边(无向)
DAG 上的任务调度拓扑排序(DFS 或 Kahn)确定执行顺序
编译依赖管理Kahn 算法天然支持循环依赖检测
社交网络社区发现Kosaraju 或 Tarjan SCC识别紧密社区
2-SAT 求解Kosaraju SCC检查变量与其否定是否同 SCC
大规模稀疏图邻接表 + BFS/DFS 空间和时间
小规模稠密图邻接矩阵 + BFS/DFS 边查询,实现简单
迷宫生成DFS(随机化)DFS 天然生成迷宫的”长走廊”结构
Web 爬虫BFS按距离递增爬取,优先爬取”近”的页面

实际应用场景汇总

1. 社交网络

  • BFS:计算两个人之间的”度数距离”(六度分隔理论)
  • SCC:发现紧密社区(互相关注的用户群)

2. 编译器

  • DFS:控制流图分析、循环检测
  • SCC:识别循环结构(基本块 SCC)
  • 拓扑排序:确定模块编译顺序

3. 路由与导航

  • BFS:无权图最短路径(如地铁线路的最少换乘)
  • DFS:路径枚举(如所有可能的路线)

4. 版本管理

  • 拓扑排序:Git 的提交排序、Makefile 的依赖编译
  • SCC:检测循环依赖

5. 网络安全

  • BFS:恶意软件传播范围分析
  • DFS:检测网络中的异常回路

6. 推荐系统

  • BFS:基于图的协同过滤(二跳/三跳邻居推荐)

与其他章节的联系

本章概念关联章节关联概念关联类型
图的表示第11章 散列表邻接表实现基础依赖
BFS 最短路径第22章 单源最短路径Dijkstra、Bellman-Ford推广关系
DFS第21章 最小生成树DFS 用于环检测应用关系
拓扑排序第22章 DAG 最短路径DAG 上的松弛顺序应用关系
SCC第22章 差分约束系统差分约束系统的可行性应用关系
并查集(连通分量)第19章 不相交集合Kruskal 中的连通分量类比关系

习题索引

20.1 图的表示

题号核心考点难度
22.1-1邻接矩阵和邻接表的转换
22.1-2邻接表表示的图上的 BFS 和 DFS
22.1-3稀疏图上邻接矩阵的 BFS/DFS 复杂度⭐⭐
22.1-4有向图的邻接表表示(入边和出边)
22.1-5邻接表和邻接矩阵的混合表示⭐⭐
22.1-6加权图的邻接表表示

20.2 广度优先搜索

题号核心考点难度
22.2-1BFS 在给定图上的执行过程
22.2-2BFS 树的性质⭐⭐
22.2-3BFS 的非递归实现⭐⭐
22.2-4BFS 的入队列顺序
22.2-5BFS 中的颜色数组简化⭐⭐
22.2-6BFS 计算最短路径树⭐⭐
22.2-7BFS 在无向图上的性质⭐⭐
22.2-8BFS 与队列的关系

20.3 深度优先搜索

题号核心考点难度
22.3-1DFS 在给定图上的执行过程
22.3-2DFS 的发现时间和完成时间⭐⭐
22.3-3括号结构定理的应用⭐⭐
22.3-4DFS 边分类⭐⭐
22.3-5DFS 的非递归实现⭐⭐⭐
22.3-6DFS 树的性质⭐⭐
22.3-7DFS 与栈的关系⭐⭐
22.3-8DFS 在无向图上的边分类⭐⭐
22.3-9DFS 在有向图上的边分类⭐⭐
22.3-10DFS 的前驱子图性质⭐⭐⭐
22.3-11DFS 与拓扑排序的关系⭐⭐
22.3-12DFS 的白色路径定理⭐⭐⭐
22.3-13DFS 的正确性证明⭐⭐⭐

20.4 拓扑排序

题号核心考点难度
22.4-1给定 DAG 的拓扑排序
22.4-2DAG 中路径计数(动态规划 + 拓扑排序)⭐⭐
22.4-3DAG 中支配顶点判定⭐⭐
22.4-4DAG 中最长路径(动态规划 + 拓扑排序)⭐⭐
22.4-5Kahn 算法(基于入度的拓扑排序)⭐⭐

20.5 强连通分量

题号核心考点难度
22.5-1给定图的 SCC
22.5-2判断图是否只有一个 SCC
22.5-3构造分量图⭐⭐
22.5-4SCC 间完成时间不等式推广⭐⭐
22.5-5分量图中 SCC 的入度和出度⭐⭐
22.5-6DFS 边分类与 SCC 的关系⭐⭐⭐
22.5-7半连通性判定⭐⭐⭐

全章习题统计: 6 + 8 + 13 + 5 + 7 = 39道题


参见Wiki

(待补充)

第20章-基本图算法 #学习/算法导论/基本图算法/章节汇总