图论算法系列 · 总纲

本讲定位:图论系列的总纲与路线图。图论是 CSP-J/S 复赛除 DP 之外的第二大板块,也是唯一一个”概念多、模板多、变形多”三者同时成立的专题——学生真正的困难从来不是背不下 Dijkstra,而是看到一道题不知道它是图论题,以及知道是图论题却选错了工具。本系列把整块图论拆成 16 讲正篇 + 2 篇番外,每讲只解决一个可独立训练的问题,用统一的一句话回答”这一讲的工具在什么信号下该被想起来”。

前置知识:数组、循环、递归、结构体、vector;栈与队列的使用(见顶层 06-linear-structures.md);会读复杂度记号。第 12 讲要用到差分思想(见顶层 07-prefix-sum-difference.md)。不需要任何图论基础。

适合对象:CSP-J 复赛已过普及组算法关(会 DFS/BFS 暴搜、会排序),目标 CSP-J 一等或 CSP-S 复赛。标 ⭐ 的内容为 CSP-S 层,标 ⭐⭐ 的为选修/超纲拓展,第一轮可整节跳过。


1. 这条线为什么单开

图论既装不进 cspj-series/(那是初赛专用,只讲选择/判断/阅读程序/完善程序),也不该塞进 dp-series/(已 01–08 完结),更不能压成顶层通用线的一两讲——它的体量相当于一整个 dp-series。所以单开 graph-series/,独立编号 01–16,与顶层通用算法线(05 高精度、06 线性结构、07 前缀和与差分、08 二分……)并行推进,两条线互不干扰、互相引用。

与已有系列的分工(写正文时严格遵守,避免重复劳动):

已有内容 在哪里 本系列怎么处理
树形 DP dp-series/05-tree-dp.md 第 11 讲只讲树的结构性质(直径、重心、DFS 序),转移方程细节指路 05 讲
DAG 上的 DP dp-series/08-dag-dp.md 第 04 讲只讲拓扑序怎么求出来和”为什么 DAG 才能递推”,状态设计指路 08 讲
状压 DP dp-series/06-bitmask-dp.md 第 16 讲讲哈密顿路时只做联系,不重讲状压
栈、队列、单调队列 06-linear-structures.md 直接当前置引用,本系列不重讲容器
序列差分 07-prefix-sum-difference.md 第 12 讲树上差分从”序列差分搬到树上”切入,明确类比
二分答案 顶层 08 讲(待写) 第 08 讲用到”二分 + 最短路判定”时交叉引用
线段树、树状数组、树链剖分 顶层数据结构线(待写) 第 12 讲末尾只给指路,不展开

2. 分讲总表

难度层含义:J = CSP-J 复赛主线,必须掌握;J⭐ = CSP-J 偶见/进阶;S = CSP-S 复赛常考;S⭐⭐ = 超出 CSP-S 常考范围的选修。

# 标题 一句话主线 难度层 代表题
01 图的存储与第一次遍历 先把”图”变成数组,再走通它 J B3643、P5318
02 图的遍历:性质与陷阱 一个 vis 数组换来 $O(n+m)$,代价是什么 J P1443、P1141、P3916
03 BFS 的进阶形态 状态即结点:多源、01-BFS、状态图搜索 J⭐ / S P1379
04 拓扑排序与 DAG 有向无环图上”谁先谁后”的唯一正确顺序 J B3644、P4017、P1983
05 最短路(一):Dijkstra 非负权图上的贪心 + 堆 J P3371、P4779
06 最短路(二):Bellman-Ford、SPFA 与负环 松弛的本质,以及负权把贪心打破之后 J / S P3385
07 最短路(三):Floyd 与全源最短路 三重循环其实是一个 DP J / S P6175、P1119
08 最短路(四):建模与变形 难的不是跑最短路,是把题目建成图 S P4568、P1144、P1073
09 并查集 只回答一个问题:这两点连通吗 J P3367、P1525
10 最小生成树 用最小代价把所有点连起来 J / S⭐ P3366、P4180、P1967
11 树上问题基础 树是最简单的图:直径、重心、DFS 序 J / S B4016、P1364、P4408
12 LCA、倍增与树上差分 把序列上的前缀和差分搬到树上 S P3379、P3128、P2680
13 强连通分量与缩点 把每个环团缩成一个点,有向图就变成了 DAG S P3387、P2341
14 割点、割边与双连通分量 哪个点/哪条边一删就断 S P3388、P2860
15 二分图 染两种颜色能不能成功,以及匹配 S P1330、P3386
16 欧拉路径与欧拉回路 一笔画的充要条件 S P7771、P2731
番外 A 差分约束与 2-SAT 把不等式组和布尔约束翻译成图 S⭐⭐ P1993、P4782
番外 B 网络流入门 最大流最小割,以及匹配的另一种视角 S⭐⭐ P3376

3. 每讲要点细化

01 图的存储与第一次遍历

点/边/度/权、有向与无向、简单图、自环与重边、连通与连通块、稀疏图与稠密图、树是特殊的图。三种存图法:邻接矩阵($O(n^2)$ 空间,$O(1)$ 查边,适合 $n \le 1000$ 与 Floyd)、vector 邻接表(好写,首选)、链式前向星(head/nxt/to/w 四数组,快且省,为网络流的成对边编号 i^1 埋伏笔)。核心表格:三种存法在”查两点是否有边”“枚举某点所有出边”“空间”三项上的对比,以及数据范围到存法的选择流程。外加第四种情况:网格图是隐式图,用 dx/dy 方向数组直接算邻居,根本不存。 本讲后半给出 DFS 与 BFS 两份最简模板(vis 一句话带过,深入留给第 02 讲),让学生学完当场能做题;例题 P5318 把”选存法 → 建图 → 遍历”完整走一遍,同时演示为什么”字典序最小”这个要求让 vector 完胜前向星。高频错误:无向图忘记存两条边、head 初始化为 $-1$ 与 $0$ 的两套写法混用、边数组开小(无向图要 $2m$)、两次遍历共用一个 vis。

02 图的遍历:性质与陷阱

不重复第 01 讲的模板,只讲”为什么对”和”哪里会悄悄错”。 先把 vis 的意义讲透——它把”枚举所有路径”压成”枚举所有点”,这是 $O(n+m)$ 的来源,代价是只保留了每个点的一次访问(后面”DFS 求不出最短路”的根子就在这)。然后是三个陷阱,每个配实测:vis 的标记时机(入队 vs 出队,稠密图上入队次数暴涨 162 倍,且无条件覆盖 dis 的版本直接错)、递归 DFS 爆栈(8 MB 约 25 万层)、DFS 冒充最短路(5000 组错 1982 组)。正面结论一条:“层数即无权最短路”的归纳法证明,务必连同”每条边长度为 1”这个前提一起记(第 03、05 讲全靠打破它推进)。三个套路:洪水填充的”圈内难判就从圈外灌”(P1162)、连通块预处理(P1141)、反向建图(P3916:正着做要 $n$ 次 DFS,反着做一次搞定)。

03 BFS 的进阶形态

多源 BFS(所有源点一起入队,等价于建超级源点);01-BFS(边权只有 0/1 时用 deque,0 边压前 1 边压后,$O(n+m)$ 顶替 Dijkstra);双向 BFS;状态图 BFS——把”局面”当结点、“一次操作”当边,用 map/康托展开判重(P1379 八数码)。收尾一句话:“当边权不全相等时 BFS 就错了,把队列换成优先队列,就是下一讲的 Dijkstra”。

04 拓扑排序与 DAG