mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4mobile wallpaper 5mobile wallpaper 6mobile wallpaper 7mobile wallpaper 8mobile wallpaper 9mobile wallpaper 10mobile wallpaper 11mobile wallpaper 12mobile wallpaper 13
11179 字
29 分鐘
树与图论基础
2026-06-03

第 7 章 树与图论基础#

本章目标:学会把关系建模为图,掌握 DFS、BFS、拓扑排序、并查集、最短路和最小生成树。


7.1 学习目标#

  1. 理解图的点、边、方向、权重、连通性。
  2. 掌握邻接表和邻接矩阵。
  3. 掌握 DFS、BFS 和拓扑排序。
  4. 掌握并查集、最短路、最小生成树。
  5. 能根据题意完成正确建图。

7.2 图的表示#

G=(V,E)G=(V,E),其中 VV 是点集,EE 是边集。

邻接矩阵适合稠密图:

space=O(n2)space=O(n^2)

邻接表适合稀疏图:

space=O(n+m)space=O(n+m)

建图时要确认:

  1. 有向还是无向。
  2. 是否有边权。
  3. 是否有重边和自环。
  4. 点编号从 0 还是 1 开始。

7.3 DFS#

DFS 适合深入探索。

void dfs(int u) {
vis[u] = true;
for (int v : g[u]) {
if (!vis[v]) dfs(v);
}
}

用途:

  • 连通块。
  • 树的遍历。
  • 环检测。
  • 拓扑排序。
  • 回溯搜索。

7.4 BFS#

BFS 按层扩展,因此能求无权图最短路。

queue<int> q;
dist[s] = 0;
q.push(s);
while (!q.empty()) {
int u = q.front(); q.pop();
for (int v : g[u]) {
if (dist[v] == -1) {
dist[v] = dist[u] + 1;
q.push(v);
}
}
}

BFS 的正确性来自:第一次访问某点时,已经是最短层数。


7.5 拓扑排序#

拓扑排序用于 DAG。

Kahn 算法:

  1. 统计每个点入度。
  2. 把入度为 0 的点入队。
  3. 每弹出一个点,就删除它的出边。
  4. 如果最终点数不足 n,说明有环。

拓扑序可用于任务依赖和 DAG DP。


7.6 并查集#

并查集维护动态连通性。

int find(int x) {
if (fa[x] == x) return x;
return fa[x] = find(fa[x]);
}
void unite(int a, int b) {
a = find(a); b = find(b);
if (a != b) fa[a] = b;
}

路径压缩后复杂度近似 O(1)O(1),严格为反阿克曼函数 O(α(n))O(\alpha(n))


7.7 Dijkstra 最短路#

适用条件:非负边权。

核心思想:每次选择当前 dist 最小的未确定点,它的最短路已经确定。

复杂度:

O((n+m)logn)O((n+m)\log n)

使用优先队列实现。


7.8 Floyd 多源最短路#

适合 n 较小的多源最短路。

状态:d[i][j]d[i][j] 表示 i 到 j 的最短路。

转移:

d[i][j]=min(d[i][j],d[i][k]+d[k][j])d[i][j] = \min(d[i][j], d[i][k] + d[k][j])

三重循环顺序:k 在最外层。


7.9 最小生成树#

给定无向连通带权图,找一棵连接所有点且边权和最小的树。

Kruskal:

  1. 按边权排序。
  2. 从小到大尝试加边。
  3. 如果两个端点不连通,就加入并合并集合。

正确性来自割性质:跨越某个割的最小边一定可以属于某棵 MST。


7.10 易错点#

  1. 无向边忘记加两次。
  2. BFS 入队时不标记 visited,导致重复入队。
  3. Dijkstra 用在负权图上。
  4. Floyd 没有初始化 d[i][i]=0d[i][i]=0
  5. 并查集没有路径压缩导致超时。
  6. 拓扑排序建边方向反了。

7.11 练习#

  1. 统计无向图连通块数量。
  2. 用 BFS 求迷宫最短路。
  3. 判断有向图是否有环。
  4. 用并查集判断网络连通性。
  5. 实现 Dijkstra 和 Kruskal。

ACM/OI 扩展:图论竞赛模板补充#

本节补充 OIer 和 ACMer 常用的算法套路、模板、复杂度分析和易错点。 写模板时默认使用 C++17,变量名尽量短,但注释要说明不变量和适用条件。

1. 并查集模板#

连通性、Kruskal、关系合并的基础结构。

struct DSU {
vector<int> p, sz;
DSU(int n = 0) { init(n); }
void init(int n) {
p.resize(n + 1); sz.assign(n + 1, 1);
iota(p.begin(), p.end(), 0);
}
int find(int x) {
while (x != p[x]) x = p[x] = p[p[x]];
return x;
}
bool unite(int a, int b) {
a = find(a); b = find(b);
if (a == b) return false;
if (sz[a] < sz[b]) swap(a, b);
p[b] = a; sz[a] += sz[b];
return true;
}
};

要点

  • 按大小合并可减少树高。
  • 带权并查集用于维护相对距离或奇偶关系。

2. 0-1 BFS#

边权只有 0 和 1 时,比 Dijkstra 更快。

deque<int> dq;
dist[s] = 0; dq.push_front(s);
while (!dq.empty()) {
int u = dq.front(); dq.pop_front();
if (vis[u]) continue;
vis[u] = 1;
for (auto [v, w] : g[u]) {
if (dist[v] > dist[u] + w) {
dist[v] = dist[u] + w;
if (w == 0) dq.push_front(v);
else dq.push_back(v);
}
}
}

要点

  • 只适用于权值 0/1。
  • 复杂度 O(n+m)O(n+m)

3. Dijkstra 模板#

非负边权单源最短路。

vector<long long> dijkstra(int s, const vector<vector<pair<int,int>>>& g) {
int n = (int)g.size() - 1;
vector<long long> dist(n + 1, LINF);
priority_queue<pair<long long,int>, vector<pair<long long,int>>, greater<>> pq;
dist[s] = 0; pq.push({0, s});
while (!pq.empty()) {
auto [d, u] = pq.top(); pq.pop();
if (d != dist[u]) continue;
for (auto [v, w] : g[u]) {
if (dist[v] > d + w) {
dist[v] = d + w;
pq.push({dist[v], v});
}
}
}
return dist;
}

要点

  • 负权边不能用 Dijkstra。
  • 堆中旧状态用 if (d != dist[u]) continue 跳过。

4. SPFA 判负环#

虽然 SPFA 容易被卡,但判负环仍常见。

queue<int> q;
vector<int> cnt(n + 1), inq(n + 1), dist(n + 1);
for (int i = 1; i <= n; ++i) q.push(i), inq[i] = 1;
while (!q.empty()) {
int u = q.front(); q.pop(); inq[u] = 0;
for (auto [v, w] : g[u]) {
if (dist[v] > dist[u] + w) {
dist[v] = dist[u] + w;
cnt[v] = cnt[u] + 1;
if (cnt[v] >= n) return true;
if (!inq[v]) q.push(v), inq[v] = 1;
}
}
}

要点

  • 多源入队可检查全图负环。
  • 最短路主力仍建议 Dijkstra/Bellman-Ford。

5. 树的直径#

无权树两次 BFS,带权树两次 DFS/Dijkstra。

要点

  • 从任意点出发找最远点 A。
  • 从 A 出发找最远点 B。
  • A 到 B 距离为树直径。

训练题型

  • 求树直径长度。
  • 求树上每个点到最远点距离。

本章模板背诵清单#

  • 能在 5 分钟内写出本章第一个核心模板。
  • 能说出每个模板的时间复杂度和空间复杂度。
  • 能说明模板不适用的反例。
  • 能为模板构造 3 个边界样例。
  • 能把模板改成 0-index 或 1-index 版本。

树上与图上常用扩展#

LCA 倍增模板#

树上路径、距离、祖先判断的基础。

const int LOG = 20;
vector<int> g[N];
int up[N][LOG], dep[N];
void dfs(int u, int p) {
up[u][0] = p;
for (int k = 1; k < LOG; ++k) up[u][k] = up[up[u][k-1]][k-1];
for (int v : g[u]) if (v != p) {
dep[v] = dep[u] + 1;
dfs(v, u);
}
}
int lca(int a, int b) {
if (dep[a] < dep[b]) swap(a, b);
int diff = dep[a] - dep[b];
for (int k = 0; k < LOG; ++k) if (diff >> k & 1) a = up[a][k];
if (a == b) return a;
for (int k = LOG - 1; k >= 0; --k) {
if (up[a][k] != up[b][k]) a = up[a][k], b = up[b][k];
}
return up[a][0];
}
  • 树上距离:dep[u]+dep[v]-2dep[lca]。
  • 根节点父亲可设为自己。
  • LOG 要满足 2LOG>n2^{LOG}>n

差分约束#

形如 xvxu+wx_v \le x_u + w 的约束可建边 uvu\to v 权 w,求最短路。

  • 判断是否有解:检查负环。
  • 最大化最小值常转化为最长路约束。
  • 不等式方向必须统一。

二分图染色#

判断图是否是二分图,用 BFS/DFS 染色。

  • 遇到已染色邻点同色则失败。
  • 奇环存在等价于不是二分图。

欧拉路径#

一笔画问题。

  • 无向图欧拉回路:所有点度数为偶数且连通。
  • 无向图欧拉路径:恰有 0 或 2 个奇度点。
  • 有向图看入度出度差。

基环树#

n 个点 n 条边的连通无向图是基环树。

  • 先拓扑删叶找到环。
  • 环外部分是若干树。
  • 常见于环上 DP + 树形 DP。

高频模板训练卡#

这一组训练卡用于把“07_树与图论基础”转化为赛场识别能力。每张卡都包含题目信号、模板选择、复杂度、反例和实现检查。

卡 1:DFS 连通块#

  • 题目信号:点边关系明显,且出现 DFS 连通块 可建模信号。
  • 优先模板:使用 DFS 连通块 模板,先确认图类型。
  • 核心不变量:访问状态、距离或集合关系在每次扩展后保持正确。
  • 复杂度目标:DFS/BFS O(n+m),Dijkstra O((n+m)log n),Floyd O(n^3)。
  • 不适用场景:边权条件不满足、图方向建反、图不连通未处理时不适用。
  • 实现检查:检查无向边双向、编号范围、重边自环、INF 溢出。
  • 边界样例:孤点、重边、自环、不连通、负边。
  • 训练题型:用 DFS 连通块 解决一道图论题并画出建图方式。

卡 2:BFS 最短路#

  • 题目信号:点边关系明显,且出现 BFS 最短路 可建模信号。
  • 优先模板:使用 BFS 最短路 模板,先确认图类型。
  • 核心不变量:访问状态、距离或集合关系在每次扩展后保持正确。
  • 复杂度目标:DFS/BFS O(n+m),Dijkstra O((n+m)log n),Floyd O(n^3)。
  • 不适用场景:边权条件不满足、图方向建反、图不连通未处理时不适用。
  • 实现检查:检查无向边双向、编号范围、重边自环、INF 溢出。
  • 边界样例:孤点、重边、自环、不连通、负边。
  • 训练题型:用 BFS 最短路 解决一道图论题并画出建图方式。

卡 3:多源 BFS#

  • 题目信号:点边关系明显,且出现 多源 BFS 可建模信号。
  • 优先模板:使用 多源 BFS 模板,先确认图类型。
  • 核心不变量:访问状态、距离或集合关系在每次扩展后保持正确。
  • 复杂度目标:DFS/BFS O(n+m),Dijkstra O((n+m)log n),Floyd O(n^3)。
  • 不适用场景:边权条件不满足、图方向建反、图不连通未处理时不适用。
  • 实现检查:检查无向边双向、编号范围、重边自环、INF 溢出。
  • 边界样例:孤点、重边、自环、不连通、负边。
  • 训练题型:用 多源 BFS 解决一道图论题并画出建图方式。

卡 4:0-1 BFS#

  • 题目信号:点边关系明显,且出现 0-1 BFS 可建模信号。
  • 优先模板:使用 0-1 BFS 模板,先确认图类型。
  • 核心不变量:访问状态、距离或集合关系在每次扩展后保持正确。
  • 复杂度目标:DFS/BFS O(n+m),Dijkstra O((n+m)log n),Floyd O(n^3)。
  • 不适用场景:边权条件不满足、图方向建反、图不连通未处理时不适用。
  • 实现检查:检查无向边双向、编号范围、重边自环、INF 溢出。
  • 边界样例:孤点、重边、自环、不连通、负边。
  • 训练题型:用 0-1 BFS 解决一道图论题并画出建图方式。

卡 5:拓扑排序#

  • 题目信号:点边关系明显,且出现 拓扑排序 可建模信号。
  • 优先模板:使用 拓扑排序 模板,先确认图类型。
  • 核心不变量:访问状态、距离或集合关系在每次扩展后保持正确。
  • 复杂度目标:DFS/BFS O(n+m),Dijkstra O((n+m)log n),Floyd O(n^3)。
  • 不适用场景:边权条件不满足、图方向建反、图不连通未处理时不适用。
  • 实现检查:检查无向边双向、编号范围、重边自环、INF 溢出。
  • 边界样例:孤点、重边、自环、不连通、负边。
  • 训练题型:用 拓扑排序 解决一道图论题并画出建图方式。

卡 6:DAG DP#

  • 题目信号:点边关系明显,且出现 DAG DP 可建模信号。
  • 优先模板:使用 DAG DP 模板,先确认图类型。
  • 核心不变量:访问状态、距离或集合关系在每次扩展后保持正确。
  • 复杂度目标:DFS/BFS O(n+m),Dijkstra O((n+m)log n),Floyd O(n^3)。
  • 不适用场景:边权条件不满足、图方向建反、图不连通未处理时不适用。
  • 实现检查:检查无向边双向、编号范围、重边自环、INF 溢出。
  • 边界样例:孤点、重边、自环、不连通、负边。
  • 训练题型:用 DAG DP 解决一道图论题并画出建图方式。

卡 7:并查集#

  • 题目信号:点边关系明显,且出现 并查集 可建模信号。
  • 优先模板:使用 并查集 模板,先确认图类型。
  • 核心不变量:访问状态、距离或集合关系在每次扩展后保持正确。
  • 复杂度目标:DFS/BFS O(n+m),Dijkstra O((n+m)log n),Floyd O(n^3)。
  • 不适用场景:边权条件不满足、图方向建反、图不连通未处理时不适用。
  • 实现检查:检查无向边双向、编号范围、重边自环、INF 溢出。
  • 边界样例:孤点、重边、自环、不连通、负边。
  • 训练题型:用 并查集 解决一道图论题并画出建图方式。

卡 8:带权并查集#

  • 题目信号:点边关系明显,且出现 带权并查集 可建模信号。
  • 优先模板:使用 带权并查集 模板,先确认图类型。
  • 核心不变量:访问状态、距离或集合关系在每次扩展后保持正确。
  • 复杂度目标:DFS/BFS O(n+m),Dijkstra O((n+m)log n),Floyd O(n^3)。
  • 不适用场景:边权条件不满足、图方向建反、图不连通未处理时不适用。
  • 实现检查:检查无向边双向、编号范围、重边自环、INF 溢出。
  • 边界样例:孤点、重边、自环、不连通、负边。
  • 训练题型:用 带权并查集 解决一道图论题并画出建图方式。

卡 9:二分图染色#

  • 题目信号:点边关系明显,且出现 二分图染色 可建模信号。
  • 优先模板:使用 二分图染色 模板,先确认图类型。
  • 核心不变量:访问状态、距离或集合关系在每次扩展后保持正确。
  • 复杂度目标:DFS/BFS O(n+m),Dijkstra O((n+m)log n),Floyd O(n^3)。
  • 不适用场景:边权条件不满足、图方向建反、图不连通未处理时不适用。
  • 实现检查:检查无向边双向、编号范围、重边自环、INF 溢出。
  • 边界样例:孤点、重边、自环、不连通、负边。
  • 训练题型:用 二分图染色 解决一道图论题并画出建图方式。

卡 10:Dijkstra#

  • 题目信号:点边关系明显,且出现 Dijkstra 可建模信号。
  • 优先模板:使用 Dijkstra 模板,先确认图类型。
  • 核心不变量:访问状态、距离或集合关系在每次扩展后保持正确。
  • 复杂度目标:DFS/BFS O(n+m),Dijkstra O((n+m)log n),Floyd O(n^3)。
  • 不适用场景:边权条件不满足、图方向建反、图不连通未处理时不适用。
  • 实现检查:检查无向边双向、编号范围、重边自环、INF 溢出。
  • 边界样例:孤点、重边、自环、不连通、负边。
  • 训练题型:用 Dijkstra 解决一道图论题并画出建图方式。

卡 11:Floyd#

  • 题目信号:点边关系明显,且出现 Floyd 可建模信号。
  • 优先模板:使用 Floyd 模板,先确认图类型。
  • 核心不变量:访问状态、距离或集合关系在每次扩展后保持正确。
  • 复杂度目标:DFS/BFS O(n+m),Dijkstra O((n+m)log n),Floyd O(n^3)。
  • 不适用场景:边权条件不满足、图方向建反、图不连通未处理时不适用。
  • 实现检查:检查无向边双向、编号范围、重边自环、INF 溢出。
  • 边界样例:孤点、重边、自环、不连通、负边。
  • 训练题型:用 Floyd 解决一道图论题并画出建图方式。

卡 12:Bellman-Ford#

  • 题目信号:点边关系明显,且出现 Bellman-Ford 可建模信号。
  • 优先模板:使用 Bellman-Ford 模板,先确认图类型。
  • 核心不变量:访问状态、距离或集合关系在每次扩展后保持正确。
  • 复杂度目标:DFS/BFS O(n+m),Dijkstra O((n+m)log n),Floyd O(n^3)。
  • 不适用场景:边权条件不满足、图方向建反、图不连通未处理时不适用。
  • 实现检查:检查无向边双向、编号范围、重边自环、INF 溢出。
  • 边界样例:孤点、重边、自环、不连通、负边。
  • 训练题型:用 Bellman-Ford 解决一道图论题并画出建图方式。

卡 13:SPFA 判负环#

  • 题目信号:点边关系明显,且出现 SPFA 判负环 可建模信号。
  • 优先模板:使用 SPFA 判负环 模板,先确认图类型。
  • 核心不变量:访问状态、距离或集合关系在每次扩展后保持正确。
  • 复杂度目标:DFS/BFS O(n+m),Dijkstra O((n+m)log n),Floyd O(n^3)。
  • 不适用场景:边权条件不满足、图方向建反、图不连通未处理时不适用。
  • 实现检查:检查无向边双向、编号范围、重边自环、INF 溢出。
  • 边界样例:孤点、重边、自环、不连通、负边。
  • 训练题型:用 SPFA 判负环 解决一道图论题并画出建图方式。

卡 14:Kruskal#

  • 题目信号:点边关系明显,且出现 Kruskal 可建模信号。
  • 优先模板:使用 Kruskal 模板,先确认图类型。
  • 核心不变量:访问状态、距离或集合关系在每次扩展后保持正确。
  • 复杂度目标:DFS/BFS O(n+m),Dijkstra O((n+m)log n),Floyd O(n^3)。
  • 不适用场景:边权条件不满足、图方向建反、图不连通未处理时不适用。
  • 实现检查:检查无向边双向、编号范围、重边自环、INF 溢出。
  • 边界样例:孤点、重边、自环、不连通、负边。
  • 训练题型:用 Kruskal 解决一道图论题并画出建图方式。

卡 15:Prim#

  • 题目信号:点边关系明显,且出现 Prim 可建模信号。
  • 优先模板:使用 Prim 模板,先确认图类型。
  • 核心不变量:访问状态、距离或集合关系在每次扩展后保持正确。
  • 复杂度目标:DFS/BFS O(n+m),Dijkstra O((n+m)log n),Floyd O(n^3)。
  • 不适用场景:边权条件不满足、图方向建反、图不连通未处理时不适用。
  • 实现检查:检查无向边双向、编号范围、重边自环、INF 溢出。
  • 边界样例:孤点、重边、自环、不连通、负边。
  • 训练题型:用 Prim 解决一道图论题并画出建图方式。

卡 16:树直径#

  • 题目信号:点边关系明显,且出现 树直径 可建模信号。
  • 优先模板:使用 树直径 模板,先确认图类型。
  • 核心不变量:访问状态、距离或集合关系在每次扩展后保持正确。
  • 复杂度目标:DFS/BFS O(n+m),Dijkstra O((n+m)log n),Floyd O(n^3)。
  • 不适用场景:边权条件不满足、图方向建反、图不连通未处理时不适用。
  • 实现检查:检查无向边双向、编号范围、重边自环、INF 溢出。
  • 边界样例:孤点、重边、自环、不连通、负边。
  • 训练题型:用 树直径 解决一道图论题并画出建图方式。

卡 17:LCA 基础#

  • 题目信号:点边关系明显,且出现 LCA 基础 可建模信号。
  • 优先模板:使用 LCA 基础 模板,先确认图类型。
  • 核心不变量:访问状态、距离或集合关系在每次扩展后保持正确。
  • 复杂度目标:DFS/BFS O(n+m),Dijkstra O((n+m)log n),Floyd O(n^3)。
  • 不适用场景:边权条件不满足、图方向建反、图不连通未处理时不适用。
  • 实现检查:检查无向边双向、编号范围、重边自环、INF 溢出。
  • 边界样例:孤点、重边、自环、不连通、负边。
  • 训练题型:用 LCA 基础 解决一道图论题并画出建图方式。

卡 18:欧拉路径#

  • 题目信号:点边关系明显,且出现 欧拉路径 可建模信号。
  • 优先模板:使用 欧拉路径 模板,先确认图类型。
  • 核心不变量:访问状态、距离或集合关系在每次扩展后保持正确。
  • 复杂度目标:DFS/BFS O(n+m),Dijkstra O((n+m)log n),Floyd O(n^3)。
  • 不适用场景:边权条件不满足、图方向建反、图不连通未处理时不适用。
  • 实现检查:检查无向边双向、编号范围、重边自环、INF 溢出。
  • 边界样例:孤点、重边、自环、不连通、负边。
  • 训练题型:用 欧拉路径 解决一道图论题并画出建图方式。

卡 19:差分约束#

  • 题目信号:点边关系明显,且出现 差分约束 可建模信号。
  • 优先模板:使用 差分约束 模板,先确认图类型。
  • 核心不变量:访问状态、距离或集合关系在每次扩展后保持正确。
  • 复杂度目标:DFS/BFS O(n+m),Dijkstra O((n+m)log n),Floyd O(n^3)。
  • 不适用场景:边权条件不满足、图方向建反、图不连通未处理时不适用。
  • 实现检查:检查无向边双向、编号范围、重边自环、INF 溢出。
  • 边界样例:孤点、重边、自环、不连通、负边。
  • 训练题型:用 差分约束 解决一道图论题并画出建图方式。

卡 20:基环树#

  • 题目信号:点边关系明显,且出现 基环树 可建模信号。
  • 优先模板:使用 基环树 模板,先确认图类型。
  • 核心不变量:访问状态、距离或集合关系在每次扩展后保持正确。
  • 复杂度目标:DFS/BFS O(n+m),Dijkstra O((n+m)log n),Floyd O(n^3)。
  • 不适用场景:边权条件不满足、图方向建反、图不连通未处理时不适用。
  • 实现检查:检查无向边双向、编号范围、重边自环、INF 溢出。
  • 边界样例:孤点、重边、自环、不连通、负边。
  • 训练题型:用 基环树 解决一道图论题并画出建图方式。

卡 21:割点桥入门#

  • 题目信号:点边关系明显,且出现 割点桥入门 可建模信号。
  • 优先模板:使用 割点桥入门 模板,先确认图类型。
  • 核心不变量:访问状态、距离或集合关系在每次扩展后保持正确。
  • 复杂度目标:DFS/BFS O(n+m),Dijkstra O((n+m)log n),Floyd O(n^3)。
  • 不适用场景:边权条件不满足、图方向建反、图不连通未处理时不适用。
  • 实现检查:检查无向边双向、编号范围、重边自环、INF 溢出。
  • 边界样例:孤点、重边、自环、不连通、负边。
  • 训练题型:用 割点桥入门 解决一道图论题并画出建图方式。

卡 22:最短路计数#

  • 题目信号:点边关系明显,且出现 最短路计数 可建模信号。
  • 优先模板:使用 最短路计数 模板,先确认图类型。
  • 核心不变量:访问状态、距离或集合关系在每次扩展后保持正确。
  • 复杂度目标:DFS/BFS O(n+m),Dijkstra O((n+m)log n),Floyd O(n^3)。
  • 不适用场景:边权条件不满足、图方向建反、图不连通未处理时不适用。
  • 实现检查:检查无向边双向、编号范围、重边自环、INF 溢出。
  • 边界样例:孤点、重边、自环、不连通、负边。
  • 训练题型:用 最短路计数 解决一道图论题并画出建图方式。

本章赛前默写任务#

  • 默写 DFS 连通块 的模板,并写出 DFS/BFS O(n+m),Dijkstra O((n+m)log n),Floyd O(n^3)。。
  • 默写 BFS 最短路 的模板,并写出 DFS/BFS O(n+m),Dijkstra O((n+m)log n),Floyd O(n^3)。。
  • 默写 多源 BFS 的模板,并写出 DFS/BFS O(n+m),Dijkstra O((n+m)log n),Floyd O(n^3)。。
  • 默写 0-1 BFS 的模板,并写出 DFS/BFS O(n+m),Dijkstra O((n+m)log n),Floyd O(n^3)。。
  • 默写 拓扑排序 的模板,并写出 DFS/BFS O(n+m),Dijkstra O((n+m)log n),Floyd O(n^3)。。
  • 默写 DAG DP 的模板,并写出 DFS/BFS O(n+m),Dijkstra O((n+m)log n),Floyd O(n^3)。。
  • 默写 并查集 的模板,并写出 DFS/BFS O(n+m),Dijkstra O((n+m)log n),Floyd O(n^3)。。
  • 默写 带权并查集 的模板,并写出 DFS/BFS O(n+m),Dijkstra O((n+m)log n),Floyd O(n^3)。。
  • 默写 二分图染色 的模板,并写出 DFS/BFS O(n+m),Dijkstra O((n+m)log n),Floyd O(n^3)。。
  • 默写 Dijkstra 的模板,并写出 DFS/BFS O(n+m),Dijkstra O((n+m)log n),Floyd O(n^3)。。
  • 为本章任选 3 个模板各写一个最小输入。
  • 为本章任选 3 个模板各写一个会使错误实现失败的反例。
  • 把本章所有模板整理到个人代码库,并标注 0-index / 1-index。

07_树与图论基础:详细训练清单#

本清单用于把章节知识拆成可执行的小任务,偏 OI/ACM 赛场使用。

训练点 1:DFS#

  • 识别信号:题面出现与“DFS”相关的限制、操作或查询时,先判断能否套用本章模型。
  • 建模步骤:写出输入对象、维护状态、允许操作、目标答案,再决定使用暴力、模板或优化。
  • 模板要求:能默写核心代码,并说明变量含义、初始化方式和循环边界。
  • 复杂度要求:写出预处理、单次操作、总复杂度,并确认能通过最大数据范围。
  • 反例检查:构造最小规模、全相等、极端值、重复值、无解或刚好可行的样例。
  • 复盘要求:若做错,记录错因是建模、证明、复杂度、边界、溢出还是模板不熟。
  • 扩展任务:把“DFS”与至少一个其他专题组合,例如二分、图论、DP、数据结构或数学。

训练点 2:BFS#

  • 识别信号:题面出现与“BFS”相关的限制、操作或查询时,先判断能否套用本章模型。
  • 建模步骤:写出输入对象、维护状态、允许操作、目标答案,再决定使用暴力、模板或优化。
  • 模板要求:能默写核心代码,并说明变量含义、初始化方式和循环边界。
  • 复杂度要求:写出预处理、单次操作、总复杂度,并确认能通过最大数据范围。
  • 反例检查:构造最小规模、全相等、极端值、重复值、无解或刚好可行的样例。
  • 复盘要求:若做错,记录错因是建模、证明、复杂度、边界、溢出还是模板不熟。
  • 扩展任务:把“BFS”与至少一个其他专题组合,例如二分、图论、DP、数据结构或数学。

训练点 3:多源 BFS#

  • 识别信号:题面出现与“多源 BFS”相关的限制、操作或查询时,先判断能否套用本章模型。
  • 建模步骤:写出输入对象、维护状态、允许操作、目标答案,再决定使用暴力、模板或优化。
  • 模板要求:能默写核心代码,并说明变量含义、初始化方式和循环边界。
  • 复杂度要求:写出预处理、单次操作、总复杂度,并确认能通过最大数据范围。
  • 反例检查:构造最小规模、全相等、极端值、重复值、无解或刚好可行的样例。
  • 复盘要求:若做错,记录错因是建模、证明、复杂度、边界、溢出还是模板不熟。
  • 扩展任务:把“多源 BFS”与至少一个其他专题组合,例如二分、图论、DP、数据结构或数学。

训练点 4:0-1 BFS#

  • 识别信号:题面出现与“0-1 BFS”相关的限制、操作或查询时,先判断能否套用本章模型。
  • 建模步骤:写出输入对象、维护状态、允许操作、目标答案,再决定使用暴力、模板或优化。
  • 模板要求:能默写核心代码,并说明变量含义、初始化方式和循环边界。
  • 复杂度要求:写出预处理、单次操作、总复杂度,并确认能通过最大数据范围。
  • 反例检查:构造最小规模、全相等、极端值、重复值、无解或刚好可行的样例。
  • 复盘要求:若做错,记录错因是建模、证明、复杂度、边界、溢出还是模板不熟。
  • 扩展任务:把“0-1 BFS”与至少一个其他专题组合,例如二分、图论、DP、数据结构或数学。

训练点 5:拓扑排序#

  • 识别信号:题面出现与“拓扑排序”相关的限制、操作或查询时,先判断能否套用本章模型。
  • 建模步骤:写出输入对象、维护状态、允许操作、目标答案,再决定使用暴力、模板或优化。
  • 模板要求:能默写核心代码,并说明变量含义、初始化方式和循环边界。
  • 复杂度要求:写出预处理、单次操作、总复杂度,并确认能通过最大数据范围。
  • 反例检查:构造最小规模、全相等、极端值、重复值、无解或刚好可行的样例。
  • 复盘要求:若做错,记录错因是建模、证明、复杂度、边界、溢出还是模板不熟。
  • 扩展任务:把“拓扑排序”与至少一个其他专题组合,例如二分、图论、DP、数据结构或数学。

训练点 6:DAG DP#

  • 识别信号:题面出现与“DAG DP”相关的限制、操作或查询时,先判断能否套用本章模型。
  • 建模步骤:写出输入对象、维护状态、允许操作、目标答案,再决定使用暴力、模板或优化。
  • 模板要求:能默写核心代码,并说明变量含义、初始化方式和循环边界。
  • 复杂度要求:写出预处理、单次操作、总复杂度,并确认能通过最大数据范围。
  • 反例检查:构造最小规模、全相等、极端值、重复值、无解或刚好可行的样例。
  • 复盘要求:若做错,记录错因是建模、证明、复杂度、边界、溢出还是模板不熟。
  • 扩展任务:把“DAG DP”与至少一个其他专题组合,例如二分、图论、DP、数据结构或数学。

训练点 7:并查集#

  • 识别信号:题面出现与“并查集”相关的限制、操作或查询时,先判断能否套用本章模型。
  • 建模步骤:写出输入对象、维护状态、允许操作、目标答案,再决定使用暴力、模板或优化。
  • 模板要求:能默写核心代码,并说明变量含义、初始化方式和循环边界。
  • 复杂度要求:写出预处理、单次操作、总复杂度,并确认能通过最大数据范围。
  • 反例检查:构造最小规模、全相等、极端值、重复值、无解或刚好可行的样例。
  • 复盘要求:若做错,记录错因是建模、证明、复杂度、边界、溢出还是模板不熟。
  • 扩展任务:把“并查集”与至少一个其他专题组合,例如二分、图论、DP、数据结构或数学。

训练点 8:带权并查集#

  • 识别信号:题面出现与“带权并查集”相关的限制、操作或查询时,先判断能否套用本章模型。
  • 建模步骤:写出输入对象、维护状态、允许操作、目标答案,再决定使用暴力、模板或优化。
  • 模板要求:能默写核心代码,并说明变量含义、初始化方式和循环边界。
  • 复杂度要求:写出预处理、单次操作、总复杂度,并确认能通过最大数据范围。
  • 反例检查:构造最小规模、全相等、极端值、重复值、无解或刚好可行的样例。
  • 复盘要求:若做错,记录错因是建模、证明、复杂度、边界、溢出还是模板不熟。
  • 扩展任务:把“带权并查集”与至少一个其他专题组合,例如二分、图论、DP、数据结构或数学。

训练点 9:二分图染色#

  • 识别信号:题面出现与“二分图染色”相关的限制、操作或查询时,先判断能否套用本章模型。
  • 建模步骤:写出输入对象、维护状态、允许操作、目标答案,再决定使用暴力、模板或优化。
  • 模板要求:能默写核心代码,并说明变量含义、初始化方式和循环边界。
  • 复杂度要求:写出预处理、单次操作、总复杂度,并确认能通过最大数据范围。
  • 反例检查:构造最小规模、全相等、极端值、重复值、无解或刚好可行的样例。
  • 复盘要求:若做错,记录错因是建模、证明、复杂度、边界、溢出还是模板不熟。
  • 扩展任务:把“二分图染色”与至少一个其他专题组合,例如二分、图论、DP、数据结构或数学。

训练点 10:Dijkstra#

  • 识别信号:题面出现与“Dijkstra”相关的限制、操作或查询时,先判断能否套用本章模型。
  • 建模步骤:写出输入对象、维护状态、允许操作、目标答案,再决定使用暴力、模板或优化。
  • 模板要求:能默写核心代码,并说明变量含义、初始化方式和循环边界。
  • 复杂度要求:写出预处理、单次操作、总复杂度,并确认能通过最大数据范围。
  • 反例检查:构造最小规模、全相等、极端值、重复值、无解或刚好可行的样例。
  • 复盘要求:若做错,记录错因是建模、证明、复杂度、边界、溢出还是模板不熟。
  • 扩展任务:把“Dijkstra”与至少一个其他专题组合,例如二分、图论、DP、数据结构或数学。

训练点 11:Floyd#

  • 识别信号:题面出现与“Floyd”相关的限制、操作或查询时,先判断能否套用本章模型。
  • 建模步骤:写出输入对象、维护状态、允许操作、目标答案,再决定使用暴力、模板或优化。
  • 模板要求:能默写核心代码,并说明变量含义、初始化方式和循环边界。
  • 复杂度要求:写出预处理、单次操作、总复杂度,并确认能通过最大数据范围。
  • 反例检查:构造最小规模、全相等、极端值、重复值、无解或刚好可行的样例。
  • 复盘要求:若做错,记录错因是建模、证明、复杂度、边界、溢出还是模板不熟。
  • 扩展任务:把“Floyd”与至少一个其他专题组合,例如二分、图论、DP、数据结构或数学。

训练点 12:Bellman-Ford#

  • 识别信号:题面出现与“Bellman-Ford”相关的限制、操作或查询时,先判断能否套用本章模型。
  • 建模步骤:写出输入对象、维护状态、允许操作、目标答案,再决定使用暴力、模板或优化。
  • 模板要求:能默写核心代码,并说明变量含义、初始化方式和循环边界。
  • 复杂度要求:写出预处理、单次操作、总复杂度,并确认能通过最大数据范围。
  • 反例检查:构造最小规模、全相等、极端值、重复值、无解或刚好可行的样例。
  • 复盘要求:若做错,记录错因是建模、证明、复杂度、边界、溢出还是模板不熟。
  • 扩展任务:把“Bellman-Ford”与至少一个其他专题组合,例如二分、图论、DP、数据结构或数学。

训练点 13:SPFA 负环#

  • 识别信号:题面出现与“SPFA 负环”相关的限制、操作或查询时,先判断能否套用本章模型。
  • 建模步骤:写出输入对象、维护状态、允许操作、目标答案,再决定使用暴力、模板或优化。
  • 模板要求:能默写核心代码,并说明变量含义、初始化方式和循环边界。
  • 复杂度要求:写出预处理、单次操作、总复杂度,并确认能通过最大数据范围。
  • 反例检查:构造最小规模、全相等、极端值、重复值、无解或刚好可行的样例。
  • 复盘要求:若做错,记录错因是建模、证明、复杂度、边界、溢出还是模板不熟。
  • 扩展任务:把“SPFA 负环”与至少一个其他专题组合,例如二分、图论、DP、数据结构或数学。

训练点 14:Kruskal#

  • 识别信号:题面出现与“Kruskal”相关的限制、操作或查询时,先判断能否套用本章模型。
  • 建模步骤:写出输入对象、维护状态、允许操作、目标答案,再决定使用暴力、模板或优化。
  • 模板要求:能默写核心代码,并说明变量含义、初始化方式和循环边界。
  • 复杂度要求:写出预处理、单次操作、总复杂度,并确认能通过最大数据范围。
  • 反例检查:构造最小规模、全相等、极端值、重复值、无解或刚好可行的样例。
  • 复盘要求:若做错,记录错因是建模、证明、复杂度、边界、溢出还是模板不熟。
  • 扩展任务:把“Kruskal”与至少一个其他专题组合,例如二分、图论、DP、数据结构或数学。

训练点 15:Prim#

  • 识别信号:题面出现与“Prim”相关的限制、操作或查询时,先判断能否套用本章模型。
  • 建模步骤:写出输入对象、维护状态、允许操作、目标答案,再决定使用暴力、模板或优化。
  • 模板要求:能默写核心代码,并说明变量含义、初始化方式和循环边界。
  • 复杂度要求:写出预处理、单次操作、总复杂度,并确认能通过最大数据范围。
  • 反例检查:构造最小规模、全相等、极端值、重复值、无解或刚好可行的样例。
  • 复盘要求:若做错,记录错因是建模、证明、复杂度、边界、溢出还是模板不熟。
  • 扩展任务:把“Prim”与至少一个其他专题组合,例如二分、图论、DP、数据结构或数学。

训练点 16:树直径#

  • 识别信号:题面出现与“树直径”相关的限制、操作或查询时,先判断能否套用本章模型。
  • 建模步骤:写出输入对象、维护状态、允许操作、目标答案,再决定使用暴力、模板或优化。
  • 模板要求:能默写核心代码,并说明变量含义、初始化方式和循环边界。
  • 复杂度要求:写出预处理、单次操作、总复杂度,并确认能通过最大数据范围。
  • 反例检查:构造最小规模、全相等、极端值、重复值、无解或刚好可行的样例。
  • 复盘要求:若做错,记录错因是建模、证明、复杂度、边界、溢出还是模板不熟。
  • 扩展任务:把“树直径”与至少一个其他专题组合,例如二分、图论、DP、数据结构或数学。

训练点 17:LCA#

  • 识别信号:题面出现与“LCA”相关的限制、操作或查询时,先判断能否套用本章模型。
  • 建模步骤:写出输入对象、维护状态、允许操作、目标答案,再决定使用暴力、模板或优化。
  • 模板要求:能默写核心代码,并说明变量含义、初始化方式和循环边界。
  • 复杂度要求:写出预处理、单次操作、总复杂度,并确认能通过最大数据范围。
  • 反例检查:构造最小规模、全相等、极端值、重复值、无解或刚好可行的样例。
  • 复盘要求:若做错,记录错因是建模、证明、复杂度、边界、溢出还是模板不熟。
  • 扩展任务:把“LCA”与至少一个其他专题组合,例如二分、图论、DP、数据结构或数学。

训练点 18:差分约束#

  • 识别信号:题面出现与“差分约束”相关的限制、操作或查询时,先判断能否套用本章模型。
  • 建模步骤:写出输入对象、维护状态、允许操作、目标答案,再决定使用暴力、模板或优化。
  • 模板要求:能默写核心代码,并说明变量含义、初始化方式和循环边界。
  • 复杂度要求:写出预处理、单次操作、总复杂度,并确认能通过最大数据范围。
  • 反例检查:构造最小规模、全相等、极端值、重复值、无解或刚好可行的样例。
  • 复盘要求:若做错,记录错因是建模、证明、复杂度、边界、溢出还是模板不熟。
  • 扩展任务:把“差分约束”与至少一个其他专题组合,例如二分、图论、DP、数据结构或数学。

训练点 19:DFS#

  • 识别信号:题面出现与“DFS”相关的限制、操作或查询时,先判断能否套用本章模型。
  • 建模步骤:写出输入对象、维护状态、允许操作、目标答案,再决定使用暴力、模板或优化。
  • 模板要求:能默写核心代码,并说明变量含义、初始化方式和循环边界。
  • 复杂度要求:写出预处理、单次操作、总复杂度,并确认能通过最大数据范围。
  • 反例检查:构造最小规模、全相等、极端值、重复值、无解或刚好可行的样例。
  • 复盘要求:若做错,记录错因是建模、证明、复杂度、边界、溢出还是模板不熟。
  • 扩展任务:把“DFS”与至少一个其他专题组合,例如二分、图论、DP、数据结构或数学。
分享

如果這篇文章對你有幫助,歡迎分享給更多人!

树与图论基础
https://lemusakuya.com/posts/study-notes/algorithm/07_树与图论基础/
作者
レム・咲く夜
發布於
2026-06-03
許可協議
CC BY-NC-SA 4.0

部分資訊可能已經過時

目錄