图论
一、图的存储与遍历
1.1 图的存储方式
-
邻接矩阵
- 适合稠密图,空间复杂度 \(O(n^2)\)
- 快速判断两节点是否相邻
-
邻接表
- 适合稀疏图,空间复杂度 \(O(n+m)\)
- 遍历邻居效率高
-
链式前向星
- 静态存储,性能优秀
- 常用于竞赛编程
1.2 图的遍历
-
深度优先搜索(DFS)
- 应用:连通分量、拓扑排序、回溯
-
广度优先搜索(BFS)
- 应用:最短路径(无权图)、层次遍历
典型例题:
-
图的连通分量计数
- 描述:给定无向图,求连通分量的数量
- 解法:DFS/BFS遍历标记
-
二分图判定
- 描述:判断图是否为二分图(二着色)
- 解法:DFS/BFS染色法
二、最短路问题
2.1 单源最短路
-
Dijkstra算法
- 适用条件:非负权边
- 时间复杂度:\(O((n+m)\log n)\)(优先队列优化)
- 例题:从源点到所有点的最短距离
-
Bellman-Ford算法
- 适用条件:含负权边,检测负环
- 时间复杂度:\(O(nm)\)
- 例题:有限制步数的最短路、负环检测
-
SPFA算法
- Bellman-Ford的队列优化
- 平均复杂度较好,但最坏仍为 \(O(nm)\)
- 可检测负环
2.2 多源最短路
- Floyd-Warshall算法
- 求所有点对间的最短路
- 时间复杂度:\(O(n^3)\)
- 空间复杂度:\(O(n^2)\)
- 应用:传递闭包、最小环
2.3 特殊最短路
-
次短路
- 求严格小于最短路长度的最短路径
- 解法:Dijkstra扩展状态
-
K短路
- 求第 \(K\) 短的路径
- 解法:A*算法、可持久化左偏树
典型例题:
-
热浪(模板题)
- 描述:求两点间最短距离
- 解法:Dijkstra
-
负环检测
- 描述:判断图中是否存在负环
- 解法:Bellman-Ford/SPFA
-
最小环问题
- 描述:求图中最小长度的环
- 解法:Floyd改进
三、最小生成树
3.1 算法分类
-
Kruskal算法
- 基于并查集
- 适合稀疏图
- 时间复杂度:\(O(m \log m)\)
-
Prim算法
- 类似Dijkstra
- 适合稠密图
- 时间复杂度:\(O(n^2)\) 或 \(O((n+m)\log n)\)
3.2 扩展问题
-
次小生成树
- 求权值第二小的生成树
- 解法:枚举不在MST中的边替换
-
最小生成树计数
- 统计最小生成树的数量
- 解法:Matrix-Tree定理
-
最小瓶颈生成树
- 最大边权最小的生成树
- 性质:最小生成树也是最小瓶颈生成树
典型例题:
-
修建公路
- 描述:连接所有城市的最小成本
- 解法:Kruskal或Prim
-
北极通讯网络
- 描述:卫星可连通部分节点,求最小传输距离
- 解法:Kruskal,当连通块数 \(\leq\) 卫星数时停止
四、拓扑排序与关键路径
4.1 拓扑排序
-
Kahn算法
- 基于入度的BFS方法
- 可检测环
-
DFS方法
- 基于出栈顺序
- 也可检测环
4.2 关键路径(AOE网)
-
最早发生时间 \(ve\)
- 正向拓扑排序计算
-
最晚发生时间 \(vl\)
- 反向拓扑排序计算
-
关键活动
- 时差为 \(0\) 的活动
典型例题:
-
课程安排
- 描述:判断课程安排是否合理(无环)
- 解法:拓扑排序
-
工程完成时间
- 描述:计算工程最短完成时间
- 解法:关键路径算法
五、连通性问题
5.1 强连通分量(有向图)
-
Tarjan算法
- 一次DFS完成
- 可同时求割点、桥
-
Kosaraju算法
- 两次DFS
- 思路直观
5.2 双连通分量(无向图)
-
割点
- 移除后使图不连通的点
- 判定:\(low[v] \geq dfn[u]\)
-
桥(割边)
- 移除后使图不连通的边
- 判定:\(low[v] > dfn[u]\)
-
点双连通分量
- 没有割点的极大子图
-
边双连通分量
- 没有桥的极大子图
典型例题:
-
受欢迎的牛
- 描述:求被所有牛崇拜的牛的数量
- 解法:强连通分量缩点
-
网络关键节点
- 描述:找出网络中的割点
- 解法:Tarjan求割点
六、二分图匹配
6.1 基本概念
-
二分图判定
- 二染色法
-
匹配
- 边集,任意两边无公共顶点
-
最大匹配
- 包含边数最多的匹配
6.2 算法
-
匈牙利算法
- 时间复杂度:\(O(nm)\)
- 实现简单
-
Hopcroft-Karp算法
- 时间复杂度:\(O(\sqrt{n} m)\)
- 适合大规模图
6.3 扩展问题
-
最小点覆盖
- König定理:最小点覆盖数 \(=\) 最大匹配数
-
最大独立集
- 顶点数 \(-\) 最大匹配数
-
最小路径覆盖
- 有向无环图:顶点数 \(-\) 最大匹配数
-
带权匹配
- KM算法(Kuhn-Munkres)
典型例题:
-
棋盘覆盖
- 描述:用 \(1 \times 2\) 骨牌覆盖棋盘
- 解法:将棋盘黑白染色,转化为二分图匹配
-
机器调度
- 描述:任务分配使完成时间最短
- 解法:二分图匹配或带权匹配
七、网络流
7.1 最大流
-
增广路算法
- Ford-Fulkerson方法
- Edmonds-Karp算法:\(O(nm^2)\)
- Dinic算法:\(O(n^2m)\),实际更快
-
ISAP算法
- 改进的预流推进算法
- 性能优秀
7.2 最小割
-
最大流最小割定理
- 最大流值 \(=\) 最小割容量
-
最小割应用
- 图的分割、项目选择
7.3 费用流
-
最小费用最大流
- SPFA找最短增广路
- 或使用Primal-Dual算法
-
最大费用最大流
- 权值取负转化为最小费用
典型例题:
-
排水系统
- 描述:求从源点到汇点的最大流量
- 解法:最大流算法
-
运输问题
- 描述:考虑运输成本的最小费用最大流
- 解法:最小费用最大流
-
二分图多重匹配
- 描述:点有容量限制的匹配
- 解法:转化为网络流
八、欧拉回路与哈密顿回路
8.1 欧拉回路/欧拉路径
-
判定条件
- 欧拉回路:所有点度为偶数(无向图)/入度\(=\)出度(有向图)
- 欧拉路径:\(0\)或\(2\)个点度为奇数(无向图)/起点出度\(=\)入度\(+1\),终点入度\(=\)出度\(+1\),其余点入度\(=\)出度(有向图)
-
Hierholzer算法
- DFS构造欧拉回路
- 时间复杂度:\(O(m)\)
8.2 哈密顿回路
-
判定
- 一般图是NP完全问题
- 竞赛中常用状态压缩DP
-
状态压缩DP解法
- 时间复杂度:\(O(n^2 \cdot 2^n)\)
典型例题:
-
一笔画问题
- 描述:判断能否一笔画并输出路径
- 解法:欧拉路径判定与Hierholzer算法
-
旅行商问题(TSP)
- 描述:访问所有城市一次后返回起点
- 解法:状态压缩DP
九、2-SAT问题
9.1 问题定义
- 给定 \(n\) 个布尔变量和 \(m\) 个形如 \((x \lor y)\) 的约束,求满足所有约束的赋值
9.2 解法
-
图论建模
- 每个变量 \(x\) 拆为两个点:\(x\)(真)和 \(\lnot x\)(假)
- 约束 \((x \lor y)\) 转化为有向边:\(\lnot x \to y\) 和 \(\lnot y \to x\)
-
强连通分量
- 如果 \(x\) 和 \(\lnot x\) 在同一强连通分量,无解
- 否则,拓扑序大的赋值为真
典型例题:
-
婚礼座位安排
- 描述:夫妻不能相邻坐,有额外矛盾限制
- 解法:转化为2-SAT问题
-
逻辑电路
- 描述:给定逻辑门和输入输出关系,判断是否可满足
- 解法:2-SAT建模
十、树上问题
10.1 基础算法
-
最近公共祖先(LCA)
- 倍增法:预处理 \(O(n \log n)\),查询 \(O(\log n)\)
- Tarjan离线算法:\(O(n+q)\)
- 树链剖分:预处理 \(O(n)\),查询 \(O(\log n)\)
-
树链剖分
- 将树分解为链,用线段树维护
- 应用:路径查询/修改、子树查询/修改
-
树的直径
- 两次DFS/BFS
- 树形DP
-
树的重心
- 删除后最大子树最小的点
- 应用:树分治
10.2 树形DP
-
没有上司的舞会
- 最大独立集问题
-
树的最小支配集/覆盖集
- 状态机DP
10.3 树上差分
-
点差分
- 路径上所有点加值
-
边差分
- 路径上所有边加值
典型例题:
-
树上距离查询
- 描述:多次查询两点间距离
- 解法:LCA
-
树上路径修改与查询
- 描述:对树上路径进行加值操作并查询
- 解法:树链剖分+线段树
-
树的中心
- 描述:找到距离所有点最远距离最小的点
- 解法:树的直径相关
十一、进阶图论
11.1 平面图
-
欧拉公式
- \(V - E + F = 2\)(连通平面图)
-
对偶图
- 应用:平面图最小割转最短路
11.2 支配树
-
定义
- 节点 \(u\) 支配 \(v\):从起点到 \(v\) 的所有路径都经过 \(u\)
-
Lengauer-Tarjan算法
- 构建支配树
11.3 图的匹配扩展
-
一般图最大匹配
- 带花树算法(Blossom Algorithm)
-
稳定婚姻问题
- Gale-Shapley算法
十二、图论建模技巧
12.1 常见建模方法
-
点权转边权
- 拆点:将点权转化为边权
-
分层图
- 处理有"次数限制"的问题
- 如:最多使用 \(k\) 次免费机会的最短路
-
状态压缩
- 将状态信息压缩到节点中
- 如:带限制的最短路
-
时间分层
- 处理与时间相关的问题
典型例题:
-
飞行路线
- 描述:有 \(k\) 次免费机会的最短路
- 解法:分层图
-
道路升级
- 描述:升级某些边使图连通的最小成本
- 解法:最小生成树变体
学习建议
- 基础先行:掌握DFS、BFS、最短路、最小生成树等基础算法
- 模板练习:每个算法类型熟练2-3道模板题
- 建模训练:重点练习将实际问题转化为图论模型
- 综合应用:尝试NOI/ACM真题,提升综合解题能力
推荐学习路径
- 图的遍历 → 最短路 → 最小生成树
- 拓扑排序 → 连通性
- 二分图 → 网络流
- 树上问题
- 进阶图论
注:图论问题关键在于建模能力,要培养将实际问题抽象为图的能力。多练习经典模型,掌握每种算法的适用场景和复杂度。竞赛中,图论问题往往综合性较强,需要灵活运用多种算法和技巧。

浙公网安备 33010602011771号