DFS
- dfs树
- 无向图:只有树边和非树边
- 每条非树边对应一个环:判仙人掌
- 对于一个联通块忽略所有非树边进行一些操作:证明,构造
- 有向图:树边、回向边、前向边、同层之间的边
- 只有树边和前向边会从dfs序小的指向大的:Dominator Tree
- 无向图:只有树边和非树边
- dfs序
- 无向图:dfs树上的每个子树对应dfs序的一个区间
- 主要是在树上使用
- 点/边双联通分量
- 有向图:强连通分量
- DAG:拓扑序
- 无向图:dfs树上的每个子树对应dfs序的一个区间
BFS
- 无向图:边只会在同一层或隔一层之间连边
- 最短路、计数
- 有向图:d(u)+w(u,v)>=d(v)
- 魔改的拓扑排序
强连通分量
- 套路1:缩点后在DAG上搞事
- 套路2:特定算法只在强连通图上有用
- 套路3:竞赛图上的强连通性
- 竞赛图缩点之后是一条链,可以动态维护强连通性
- 竞赛图上各种计数
双联通分量
- 熟练掌握点双和边双求法
- 点双:边不重复,重复的点叫割点
- 边双:点不重复,不存在的边叫桥
- 套路1:把边双缩成树之后搞事
- 套路2:把点双建成圆方树之后搞事:图上两点之间所有路径的并等价于圆方树上两点的路径
- 套路3:动态维护双联通性
最短路
- SPFA:它死了
- OI中能用Dijkstra算法一定不要用SPFA
- 套路1:删点/边之后询问最短路:在最短路树上删点/边
- 套路2:在最短路图上搞事情(注意当有零环时不一定是DAG,需要特殊处理)
- 套路3:各种奇妙的优化建图
- 线段树优化、分块优化
- 通过分析删掉不可能用到的边
- 边权小可以用桶代替堆
- 套路4:差分约束系统
- 如果限制形如f(x)-f(y)<=w(x,y)就能转化成最短路,相当于最短路的对偶
- 差分/前缀和为变量
- 可能会出现负数
K短路
- 掌握O(k log k + m log n)的做法(可并堆)
- 求第k优方案:构造图使得每个方案对应一条路径
欧拉回路
- 有向/无向图上欧拉路/欧拉回路求法
- 套路1:给无向图定向使每个点度数= -1/ 0 / 1
- 套路2:构造
2-SAT
- 熟练掌握求解方法
- 套路1:优化建图
- 各种数据结构优化
- 前缀、后缀优化
- 建立辅助变量
- 套路2:魔改部分限制
- 相当于图中加边/删边
- 可能需要bitset求连通性
- 套路3:各种魔改形式的SAT问题
最小生成树
- 掌握Prim/Kruskal/Boruvka算法
- 套路1:最小瓶颈路为最小生成树上的路径
- 套路2:动态最小生成树(加边):lct维护,每次加边都删除路径上最大的一条边
- 套路3:动态维护图的连通性:以边的删除时间维护最大生成树
- 套路4:完全图的最小生成树,权值为点权的某种操作
- 去掉无用边:曼哈顿距离(莫队算法乱搞用),gcd
- 用Boruvka/Prim,数据结构维护最小出边:XOR
- 扩展:最小生成环套树(Codeforces 875F)
- 改动Kruskal算法
- 正确性:未选择的边一定不在答案内
- 扩展:次小生成树
仙人掌
- 大多数都可以转化为圆方树上的dp。
- 由于特殊性质也可以改动圆方树,使得单独一条边不构成点双。
- 仙人掌上的数据结构
杂项
- 给定每个点的度数,构造满足条件的无向图/树
- 要求没有重边:
- 每次选两个度最大的点连?
- 每次选一个度最大的点和一些点连(充要条件)
- 不要求没有重边:
- 只要求最大点度不超过总度数的一半,且总数是偶数
- 每次选两个度最大的点连边
- 树:
- 只要求和为2n-2,且每个点至少是1
- 构造使用prufer序列
- 线性代数黑科技
- 在无向图的dfs树上给每个非树边分配一个随机整数权值
- 树边权值等于覆盖它的非树边权值异或
- 一组边集是割集当且仅当对应的权值线性无关
- Dominator Tree:至少应该知道DAG上的做法,以及当点数少时的压位做法。
- Steiner Tree:掌握裸的dp
- 网格图算法:分治、dp
- 平面图算法:对偶
网络流预备知识
- 在所有边的容量都是1的图上:O(min(V2/3,E1/2)E)
- 在存在一层容量都是1的分层图上:O(E1/2E)
- 在单位网络上:O(V1/2E)
二分图匹配
- 最大匹配/最大权匹配
- 最小点覆盖/最小权点覆盖<=>最大独立集/最大权独立集
- 最小边覆盖/最小权边覆盖
- 求方案
- 套路1:对于匹配的调整 参见最大流/费用流的调整
- 套路2:Hall定理
- 当且仅当一侧任意子集都>=邻居个数
- 需要对题目性质的分析
- 套路3:w(u)+w(v)>=或<=s(u,v)的限制转化为KM求顶标
- 套路4:各种优化建图
- 数据结构、分块、辅助节点
- 只能使用网络流