⚠ 当前无法加载公式渲染库(KaTeX 走 CDN),公式可能显示为原始代码——联网后刷新即可。
算法设计与分析 · 课程笔记 · 模块 4(P/NP/NPC + 网络流 + 近似 + 考试要点)

模块 4 · NP 理论、网络流、近似算法 与 考试要点

依据:什么是P问题NP问题NPC问题.ppt(22 页)+ CH05 §5.2 + 2021 复习大纲 + Review-v2 + 历年试题 整理日期:2026-09-25
本科遗忘急救站 · 多项式时间归约方向与残余网络直觉

0 · 彻底告别“归约方向写反”:\(A \le_p B\) 的 10 秒记忆口诀

  • 不等号开口朝向谁,谁就更难(至少一样难)!写 \(A \le_p B\)(把问题 \(A\) 多项式归约到问题 \(B\)),就像实数比大小 \(3 \le 5\):右边 \(B\) 的难度 \(\ge\) 左边 \(A\) 的难度!
  • 证明某新问题 \(X\) 是 NP 完全(NPC)的铁律方向:你必须找一个已知的 NPC 老问题 \(A\),把已知难的 \(A\) 归约到待证的 \(X\),即证明 \(\text{已知 NPC } A \le_p \text{待证 } X\)!(逻辑:如果 \(X\) 能轻松解,那通过归约转换,难问题 \(A\) 也能轻松解,从而 \(X\) 至少和 \(A\) 一样难;千万别反过来把 \(X\) 归约到 \(A\)!)。

自学导航 · NP 完全与网络流:大题证明模板

① 前置知识与记号

NP 完全证明:先说明目标判定问题属于 NP,再选择已知 NP 完全问题 A,构造多项式归约 A≤ₚB,并证明实例有解当且仅当映射后的实例有解。归约方向是常见扣分点。

② 完整例题

网络流例题:s→a 容量 3、s→b 容量 2、a→t 容量 2、b→t 容量 2、a→b 容量 1。给出两条各 2 的路径流可达到 4;割 {s,a,b}|{t} 容量 4,故最大流就是 4。

💡 破题关键与第一步提示(遮答案自测用 · ③ 考前自测(展开题目))

破题切入点:为什么给出可行流只能证明最大流下界,而给出割容量只能证明上界?(👉 先合上下方完整推导,自己动手算完关键步再核对踩分点!)

📝 完整规范推导与评分踩分点(③ 考前自测(展开题目))

为什么给出可行流只能证明最大流下界,而给出割容量只能证明上界?

本栏是补充学习材料,考试范围以本学期教师正式通知为准。

考点精练 · 教学型推导与标准答题

考试证明:从 3-SAT 到 CLIQUE 的归约方向

证明 CLIQUE 是 NP 完全问题时,可以使用已知 NP 完全的 3-SAT。

  1. 属于 NP:证书是 \(k\) 个顶点,检查每对顶点之间都有边,所需时间为多项式。
  2. 构造:给每个子句的每个文字出现建立顶点;仅在不同子句、且两个文字不互为否定时连边;令所求团大小 \(k\) 等于子句数。
  3. 充分性:若公式可满足,从每个子句选择一个为真的文字,则来自不同子句且不会互为否定,这些顶点两两相连,形成大小为 \(k\) 的团。
  4. 必要性:大小为 \(k\) 的团最多取每个子句一个顶点,恰好覆盖全部 \(k\) 个子句;所选文字之间无矛盾,可同时赋为真,因此公式可满足。
  5. 时间:顶点数与文字出现次数同阶,建边至多二次,故为多项式归约。
💡 破题关键与第一步提示(遮答案自测用 · 自测:为什么不能反过来只证明 CLIQUE \(\le_p\) 3-SAT?)

破题切入点:要证明 CLIQUE 至少和一个已知 NP 难问题一样难,需要从已知难题归约到 CLIQUE;(👉 先合上下方完整推导,自己动手算完关键步再核对踩分点!)

📝 完整规范推导与评分踩分点(自测:为什么不能反过来只证明 CLIQUE \(\le_p\) 3-SAT?)

要证明 CLIQUE 至少和一个已知 NP 难问题一样难,需要从已知难题归约到 CLIQUE;反向归约只表明 CLIQUE 不比 3-SAT 难,无法推出它 NP 难。

网络流拿分结构:先画残量网络、说明可增广路径;最后必须给出容量与流量相等的 \(s\)-\(t\) 割,才构成最优性证明。仅报告一组可行流不够。

修订版 · 重点核对

先看:本模块易错点与补充

严谨性勘误
  • 一个问题在 co-NP 并不能据此断言它不在 NP;图中“不存在 Hamilton 回路”的复杂性归属不能被写成已知 NP 之外。
  • 顶点覆盖线性松弛的 1/2 阈值取整可给 2-近似;最大独立集不能照搬这个取整规则。
  • NP-hard 不等于“不在 NP”;归约方向是“已知 NP-hard → 目标问题”;Edmonds–Karp 用 BFS 避免 Ford–Fulkerson 路径策略导致的效率/终止性风险。
  • 最大流的 Python 实现:Edmonds–Karp;复杂性证明课堂版与工程编码版分开练习。

0 · 本模块说明(源材料声明)

先说清楚什么来自哪里 P/NP/NPC 概念:来自课件《什么是P问题、NP问题和NPC问题.ppt》+ CH05 §5.2。归约链、网络流、近似算法:来自 2021年复习大纲(被列入该年份的复习范围),但 CH 系列课件未覆盖——本模块按大纲要求与教材(王晓东第 4 版、屈婉玲参考书)补写,是对旧大纲涉及、但 CH 系列课件未展开专题的学习补充;是否属于本学期考试范围,请以任课教师通知为准。题型与答题规范:来自 Review-v2 与大纲 S11–16。
历史大纲中这些知识如何出题 大纲预计题目类型:判断 10 题(20 分)+ 简单计算 20–30 分,其中计算题构成为“渐进式 1 + 贪心 1 + 分治递归式 1 + DP 1 + 最大流最小割 1 + 归约与 NPC 证明 2–3 题 + 近似算法 1”。这些是 2021 年旧大纲列出的题型,不能据此推算 2026 年分值或必考题数。
先修自查 · 这一模块要带的东西 ①多项式时间的直觉(O(n^k) vs 指数级);②图的基本语言:有向/无向、容量、s-t 割、流守恒;③"松弛 / 取整"思想(近似算法用,会叙述即可);④模块 3 末尾的 P/NP/NPC/NPH 四定义与"归约方向"——本模块全部建立在它们上,忘了先回去。
答题规范(证明题得分点,大纲原话细化) NPC 证明两步模板缺一不可:① 把已知 NPC 问题 A 构造成问题 X 的实例(写出构造细节);② 证等价性(双向 iff:"A 有解 ⟺ X 有解"两个方向都写);③ 补一句"该构造是多项式时间"。网络流大题:必须逐条列出增广路径及流量,最后给出最大流值并指出最小割(S 侧顶点集)。近似算法:算法描述 + 近似比怎么得出来。
数学手生?增长率比较(对数<幂<指数)、求和公式、矩阵运算的"三分钟复习"在上级目录 《数学基础工具箱》第 3、4、5 节;考前看第 8 节"急救包"。

1 · 优化问题 vs 判定问题CH05 S22–23; 大纲第1章

两类抽象问题 优化问题(极值问题)四部分:实例集合 D、每个实例的可行解集 S(I)、目标函数 c(σ),求最优(如“最优 TSP 路线”)。
判定问题(识别问题):答案只有“是/否”,即映射 \(I\to\{0,1\}\)(如“是否存在长度 ≤k 的路线”)。
严格的 NP-complete 分类主要针对判定问题;优化问题通常讨论 NP-hard 与其判定版本;优化问题转判定的标准手法:加阈值 k(“是否存在代价 ≤k 的解”)。大纲还要求“自身归约”——用判定版解优化版,见 §5。

2 · P / NP / NPC / NPH 四件套 ★P/NP课件; CH05 S24–33

定义(一字不差地记)
类定义关键词
P存在多项式时间求解算法的判定问题多项式解决
NP给定一个候选解,能在多项式时间内验证其正确性的判定问题多项式验证(≠“非P”!)
NPC①属于 NP;②NP 中任何问题都可多项式归约到它(两条同时满足)NP 中最难的一层
NPH只要求条件②(NP-hard 可同时属于 NP,此时也是 NPC)可以不属于 NP;范围比 NPC 广
验证 vs 求解(课件“RP 很好”比喻) 最短路径问“有没有 <100 的路”:找到很难,但验证“你给的路长 98”只要 O(n)——猜对就有多项式解 ⟹ NP。反例:“图中是否不存在 Hamilton 回路”——猜“不存在”无法多项式验证(得穷尽所有路),它的补问题属于 NP,因此该问题属于 co-NP;是否也属于 NP 一般未知(不能未经证明声称不属于 NP)。NP 定义的非对称性(大纲点名)就在这里:能验证“是”≠能验证“否”。
核心事实(判断题弹药库)
  • \(P\subseteq NP\)(能解当然能验证);P=NP?未解决,学界共识 P≠NP;
  • 任一 NPC 问题找到多项式算法 ⟹ P=NP(所有 NP 问题都归约到它)——“正是 NPC 的存在使人们相信 P≠NP”;
  • 第一个 NPC 问题:逻辑电路可满足性(Circuit-SAT),Cook(1971);此后 Hamilton 回路、TSP(判定版)等相继入列;
  • 经典 NPC 清单:SAT / 3-SAT、0-1 背包(判定版)、子集和 Subset-Sum、划分 Partition、TSP(判定)、Hamilton 回路、顶点覆盖 VC、团 Clique、独立集 IS、图的 3 着色;
  • 若 P≠NP:P∩NPC=∅(NPC 全在“NP∖P”的边沿)。
四集合关系图(会画!) P 在 NP 内部;NPC 是 NP 的“最上沿”一圈;NPH 溢出 NP 之外(如优化版 TSP——不属于判定问题但仍 NP 难)。考题常给图问“某区域代表什么”。

3 · 归约 ≤p:方向就是一切 ★P/NP课件 S15–16; CH05 S28–30

定义与直观 A 可多项式归约到 B(\(A\le_p B\)):存在多项式时间映射 f,把 A 的任意实例 α 变为 B 的实例 β=f(α),且答案一致(α“是” ⟺ β“是”)。直观意义:会用 B 解 A ⟹ B 至少和 A 一样难(B 不比 A 容易)。归约可传递:A≤pB, B≤pC ⟹ A≤pC。
方向判断题清单(每年必错一片)
命题对错
若 A≤pB 且 B 可多项式求解,则 A 可多项式求解✓(解 B 的算法 + 映射 f 解 A)
若 A≤pB 且 A 很难,则 B 至少同样难✓(NPC 证明的原理)
若 A≤pB 且 A 是 NP 难,则 B 也是 NP 难✓(B1 卷第 2 题答案 √;B2 卷同题答案相反——B2 有误,以数学推导为准)
若 A≤pB 则 B≤pA✗(归约不对称)
证明 X 是 NPC 应把 X 归约到 SAT✗ 方向反!应是已知 NPC 问题 ≤p X
归约映射本身需多项式时间完成才有意义✓

4 · NPC 证明模板 ★★(大题 2–3 道)大纲 S7–S9, S16

两步模板(照结构写即得分) 要证判定问题 X 是 NPC:
  1. 证 X∈NP:给出候选解后存在多项式时间验证算法(写出来,如“检查子集和恰为 t:O(n)”);
  2. 选已知 NPC 问题 A,构造 A ≤p X:
    a. 给出映射:A 的任意实例 α 如何多项式时间构造 X 的实例 β=f(α)(写公式);
    b. 证正确性(双向 iff):α“是”⟹β“是”,且 β“是”⟹α“是”;
    c. 说明 f 是多项式时间。
    由传递性,所有 NP 问题 ≤p X。
1+2 ⟹ X∈NPC。∎
示范 · 3-SAT ≤p 团(最常默写的模板题)
3-SAT 公式(k 个子句、每句 3 文字)→ 图 G:每个文字一个顶点(3k 个);同一子句内不连边;互补文字对之间不连边(xᵢ~¬xᵢ),其余连边;团大小 = k。
  • 可满足 ⟹ 每句取一个真文字,这 k 个顶点两两有边 ⟹ k-团;
  • k-团 ⟹ k 顶点分布于不同子句且无互补对 ⟹ 给这些文字赋真 ⟹ 可满足。∎
答题主旨(大纲 S16 原话) 先选好已知 NPC 问题 A → 给出 A 实例到 B 实例的构造方法 → 再证明归约的正确性。三段缺一不可,只写“由 NPC 定理知”不给分。

5 · 大纲归约链精讲大纲 S7; 自身归约

大纲点名的三条链(会构造)
归约构造
Subset-Sum ≤p Knapsack子集和实例 {a₁,…,aₙ}, 目标 t → 背包:wᵢ=vᵢ=aᵢ,容量 C=t(判定版)。因价值=重量,最大可装价值 = 不超 t 的最大子集和;其=t ⟺ 存在子集和恰为 t
Subset-Sum ≤p Partition实例 {aᵢ}, 目标 t,S=Σaᵢ → 划分实例加两个数 \(t+1\) 与 \(S-t+1\)。总和 2S+2,两半各 S+1;存在等分 ⟺ 存在子集和为 t(含 t+1 的一侧需补足 S−t)
Partition ≤p 负载均衡划分实例 {aᵢ} → 2 台机器负载均衡,作业时间 aᵢ。存在 makespan=S/2 的调度 ⟺ 存在等划分(k-Load-Balance 取 k=2)
自身归约:优化 ≤p 判定(大纲点名 VC/Hamilton/3-Color/Subset-Sum) 以顶点覆盖为例:先用判定版(“存在大小 ≤k 的覆盖?”)找到最小 k(从 1 试到 n 或二分);再逐个顶点 v 问:“删去 v 后仍存在大小 k−1 的覆盖吗?”是 ⟹ v 属于某最优覆盖,固定 v,k−1,继续;否 ⟹ v 必不在(当前实例的)最优覆盖中,从图中去掉其覆盖的边继续。n 轮构造出具体解。Hamilton 回路(逐边试探)、3-Color(逐顶点定色)、Subset-Sum 同法。==这就是“优化问题多项式归约到自身的判定问题”==。
🚨 期末大题铁律:要证新问题 B ∈ NPC,归约箭头必须从【已知 NPC 问题 A ≤ₚ 待证问题 B】(方向反了直接零分!) SAT Cook定理源头 ≤ₚ 3-SAT 每子句3文字 ≤ₚ 最大团 Clique G有大小k的团 取补图Ḡ 顶点覆盖 VC Ḡ有|V|-k覆盖 ≤ₚ 子集和 Subset Sum ≤ₚ 0-1背包 判定版 哈密顿回路 HC 经过每顶点恰好1次 TSP 判定 边权0/1转化 ★ 三大等价桥:G 有 k-团 ⟺ Ḡ 有 k-独立集 ⟺ Ḡ 有 (|V|-k)-顶点覆盖
图:算法课大纲核心 NP 完全问题多项式归约树(SAT → 3-SAT → 团 → 独立集/顶点覆盖 → 子集和/背包 & HC → TSP)

6 · 网络流:最大流最小割 ★大纲第3章(课件未含,按教材补)

定义 流网络 \(G=(V,E)\):有向图,边容量 c(e)≥0,唯一源 s、汇 t。流 f 满足:①容量约束 0≤f(e)≤c(e);②守恒约束(除 s,t 外流入=流出);|f| = s 的净流出。最大流问题:求 |f| 最大。
s-t 割:划分 V=S∪T(s∈S, t∈T),容量 \(c(S,T)=\sum_{e: S\to T}c(e)\)(只算正向边)。
定理与算法 ★★
  1. 弱对偶:任意流与任意割:|f| ≤ c(S,T)。
  2. 增广路径:残量网络中 s→t 的路径(可走正向残量边或反向退流边),沿其增广 Δ=最小残量。
  3. 最大流最小割定理:以下等价——f 是最大流 ⟺ 残量网络无增广路径 ⟺ 存在割 (S,T) 使 |f|=c(S,T)。最大流值 = 最小割容量。
  4. Ford–Fulkerson:不断找增广路径;Edmonds–Karp 用 BFS 找最短增广路径,O(VE²)(与容量数值无关——FF 原始版对整数容量的增广次数最坏可受最大流值影响,对无理容量甚至可能不终止,判断题点)。
  5. 求最小割:最大流跑完后,残量网络中 s 可达的顶点集 = S,其余 = T,(S,T) 即最小割。
典型题流程(大纲原话:要列出各条增广路径!)
①全零流起;②逐条找增广路径 P₁, P₂, …(BFS 最短优先),沿每条增广 Δ=最小残量,把每条路径与 Δ 写出来(过程分);需要退流时写反向增广;③无增广路径停:|f|=ΣΔ=最大流;④残量网络 s 可达集=S,(S,T) 为最小割,容量=|f|。∎
相关判断题:最小割不一定唯一(年份C卷);最大流值=最小割容量 √。
📄 期末禁止写代码:最大流 Edmonds–Karp 最短增广路算法 · 自然语言标准作答四步模板
  1. ① 状态/子问题定义与符号声明:给定容量网络 \(G=(V,E,c)\)、源点 \(s\) 与汇点 \(t\)。对当前可行流 \(f\),构造残留网络 \(G_f\):正向剩余容量 \(c_f(u,v)=c(u,v)-f(u,v)\),反向退流容量 \(c_f(v,u)=f(u,v)\)。
  2. ② 核心递推方程 / 贪心策略 / 搜索剪枝准则:最大流最小割定理:流 \(f\) 是最大流 \(\iff G_f\) 中不存在从 \(s\) 到 \(t\) 的增广路 \(\iff |f|=c(S,T)\)。Edmonds–Karp 策略:每轮在残留网络 \(G_f\) 中使用广度优先搜索(BFS)寻找边数最少的 \(s\to t\) 增广路 \(p\),其瓶颈残量 \(\Delta = \min_{(u,v)\in p} c_f(u,v)\)。
  3. ③ 算法自然语言分步流程(严禁贴 C/Python 语法):第一步:初始化残留矩阵等于原容量矩阵,总流量 \(total=0\);第二步:在 \(G_f\) 中从 \(s\) 出发跑 BFS(仅走 \(c_f(u,v)>0\) 的边)并记录前驱数组 \(parent\);第三步:若汇点 \(t\) 未被访问则已达最大流,退出循环;第四步:沿 \(parent\) 从 \(t\) 逆推回 \(s\) 求最小残量 \(\Delta\),再沿路径将正向残量减 \(\Delta\)、反向残量加 \(\Delta\),累加 \(total += \Delta\) 并重复第二步。
  4. ④ 时间与空间复杂度严格推导:由于按最短边数 BFS 增广,每个顶点到源点的最短距离单调不减,总增广次数上界为 \(O(VE)\);每次 BFS 耗时 \(O(E)\),故总时间复杂度 \(O(VE^2)\),空间复杂度 \(O(V^2)\)(邻接表为 \(O(V+E)\))。
🐍 Python 求职机试标准实现(源自 practice_algorithms.html · 在线阅读器)
def edmonds_karp(capacities, source, sink):
    """有向图容量矩阵最大流,允许整数容量。Edmonds–Karp O(VE²)。"""
    n = len(capacities)
    if not n or source == sink or not 0 <= source < n or not 0 <= sink < n:
        raise ValueError('源汇不合法')
    if any(len(row) != n or any(c < 0 or not isinstance(c, int) for c in row) for row in capacities):
        raise ValueError('容量须非负整数方阵')
    res = [list(row) for row in capacities]
    total = 0
    while True:
        parent = [-1] * n
        parent[source] = source
        todo = deque([source])
        while todo and parent[sink] == -1:
            u = todo.popleft()
            for v, c in enumerate(res[u]):
                if c > 0 and parent[v] == -1:
                    parent[v] = u
                    todo.append(v)
                    if v == sink:
                        break
        if parent[sink] == -1:
            break
        v = sink
        delta = float('inf')
        while v != source:
            u = parent[v]
            delta = min(delta, res[u][v])
            v = u
        v = sink
        while v != source:
            u = parent[v]
            res[u][v] -= delta
            res[v][u] += delta
            v = u
        total += delta
    return total
① 原网络可行流 f/c 与最小割 (S, T) s u v t 12/16 11/13(跨割) 0/10 12/12(满流) 11/14 最小割 S={s,u}, T={v,t} 割容量 c(S,T) 只算 S→T 正向原容量和(不减 T→S) ② 残留网络 G_f(绿: 正向残量 c-f · 橙: 反向退流 f) s u v t c_f=4 退流12 c_f=2 仅反向 12 c_f=3 增广瓶颈 Δ:正向残量 -Δ,反向退流边残量 +Δ
图:网络最大流最小割定理与残留网络 G_f(满流边正向残量为 0,反向退流边容量等于已流流量 f(u,v))

7 · 近似算法 ★大纲第5章(课件未含,按教材补)

为什么需要 NPC 问题没有多项式精确算法(除非 P=NP)。退而求其次:多项式时间 + 保证输出不超过最优值的 ρ 倍——ρ 叫近似比(最小化:ALG ≤ ρ·OPT;最大化:ALG ≥ OPT/ρ)。

7.1 负载均衡的近似算法(大纲点名证明)

列表调度 List Scheduling ≤ (2−1/m)·OPT 策略:作业逐个放到当前负载最小的机器。证明:设最后完工机器 i 的最后放入作业长 pⱼ、开工时刻 t,则 ALG=t+pⱼ。①机器 i 此前一直忙 ⟹ Σp ≥ m·t+pⱼ ≥ mt ⟹ t≤OPT(因 OPT ≥ Σp/m);②pⱼ≤p_max≤OPT。故 ALG≤2·OPT(精确式 2−1/m)。LPT 版(长作业先排序)改进为 \(\frac43-\frac1{3m}\)。∎

7.2 带权顶点覆盖的定价算法(Pricing)≈ 2 倍

算法与证明(大纲点名) 算法:C=∅;每条未覆盖边 (i,j) 定价 p_e,两端各记账 p_e;涨价直到某端点“紧”(累计记账=权重 w),紧点入 C;循环至无边未覆盖。
2 倍证明:①停价时 p_e ≤ 两端点各自权重(紧点恰加满,另一点未满)。对最优覆盖 OPT:每条边记到它的某个 OPT 端点上 ⟹ \(\sum_e p_e\le\sum_{i\in OPT}w_i=\mathrm{OPT}\)。②紧点 i 记账 \(\sum_{e\ni i}p_e\le w_i\),每条被覆盖边至少一个紧端点,故 \[\mathrm{cost}(C)=\sum_{i\in C}w_i\le\sum_{i\in C}\sum_{e\ni i}p_e\le 2\sum_e p_e\le 2\,\mathrm{OPT}.\] ∎(价格分摊论证)

7.3 整数规划建模(大纲点名)

两个标准模型 + 松弛 带权顶点覆盖:\(\min\sum_i w_ix_i\),s.t. \(x_i+x_j\ge1\ \forall(i,j)\in E\),\(x_i\in\{0,1\}\)。
最大独立集(B1 卷大题):\(\max\sum_i x_i\),s.t. \(x_i+x_j\le1\ \forall(i,j)\in E\),\(x_i\in\{0,1\}\)。
松弛:放宽为 \(x_i\in[0,1]\) 得线性规划 LP(多项式可解),对顶点覆盖问题可按 xᵢ≥1/2 取 1 得到可行的 2-近似;最大独立集不能按同一阈值逐点取整(可能两相邻顶点同时选中)——“建模→松弛→取整”三段式。

7.4 0-1 背包的近似(大纲:取整法)

两条 ① 1/2 保证(最大化问题的 2-近似):先去掉重量超过容量的不可行物品;其余按价值/重量比降序依次取完整物品,遇到第一个放不下的物品即停止,得到一个前缀解。另取单件价值最大的可行物品,返回二者价值较高者。证明:分数背包松弛的最优值至多为“前缀总价值 + 下一件的价值”,而下一件的价值不超过最大可行单件价值,故返回值至少是 OPT/2。若全部装得下则已经最优。
② 价值缩放 FPTAS(\(1-\varepsilon\) 保证):假设物品价值非负且 \(0<\varepsilon<1\)。先丢弃重量超过容量的物品;记剩余 n 件中最大价值为 \(v_{\max}\),取 \(K=\varepsilon v_{\max}/n\),令 \(\tilde v_i=\lfloor v_i/K\rfloor\)。用“获得给定缩放总价值所需的最小重量”作 DP,缩放总价值上限 \(O(n^2/\varepsilon)\),标准实现时间 \(O(n^3/\varepsilon)\)、滚动数组空间 \(O(n^2/\varepsilon)\)。每件损失小于 K,累计小于 \(nK=\varepsilon v_{\max}\le\varepsilon\,\mathrm{OPT}\),所以还原后的价值至少为 \((1-\varepsilon)\mathrm{OPT}\)。若无可行物品,最优值为 0,可直接返回空集。
📄 期末禁止写代码:顶点覆盖 2-近似算法(基于极大匹配) · 自然语言标准作答四步模板
  1. ① 状态/子问题定义与符号声明:给定无向图 \(G=(V,E)\),求顶点子集 \(C\subseteq V\) 覆盖所有边且 \(|C|\) 尽可能小。算法维护当前未覆盖边集 \(E'\)、近似覆盖集 \(C\) 以及隐式挑选出的边不相交极大匹配 \(M\)。
  2. ② 核心递推方程 / 贪心策略 / 搜索剪枝准则:近似策略与下界松弛:每轮任取一条尚未覆盖的边 \((u,v)\in E'\),将两个端点 \(u\) 和 \(v\) 同时加入覆盖集 \(C\),并删去与 \(u\) 或 \(v\) 关联的所有边。由于被选出的边集 \(M\) 两两不共端点,任何合法覆盖 \(C^*\) 至少要在 \(M\) 的每条边上各取 1 个端点,即 \(|C^*|\ge |M|\)。
  3. ③ 算法自然语言分步流程(严禁贴 C/Python 语法):第一步:初始化覆盖集 \(C=\varnothing\),已覆盖顶点标记集为空;第二步:遍历边集 \(E\) 中每条边 \((u,v)\),若 \(u\) 和 \(v\) 均未被标记,则将 \(u,v\) 一并加入 \(C\) 并标记 \(u,v\) 已覆盖(等价于删去所有与 \(u,v\) 关联的边);第三步:扫描完毕后返回 \(C\)。
  4. ④ 时间与空间复杂度严格推导:只需单次遍历边集并用哈希集判重,时间复杂度 \(O(V+E)\)(多项式时间);近似比证明:\(|C| = 2|M| \le 2|C^*|\),故恒满足近似比 \(\rho(n) = 2\)。
🐍 Python 求职机试标准实现(源自 practice_algorithms.html · 在线阅读器)
def vertex_cover_approx(edges):
    """极大匹配 2-近似顶点覆盖算法。O(V + E) 时间,近似比 ρ = 2。"""
    covered = set()
    cover = []
    for u, v in edges:
        if u not in covered and v not in covered:
            covered.add(u)
            covered.add(v)
            cover.extend([u, v])
    return cover

8 · 考试题型与答题模板 ★★大纲 S11–16; Review S93–119

考试信息(2021 大纲)
2021 年资料记载时长 2 小时、中文卷及部分选做题;其中关于分数分布的历史预测不用于当前备考。(Review 版另载:选择 20% + 判断 20% + 填空 30% 含算法填空 + 问答 10% + 算法设计 20%,平时 60% + 期末开卷 40%——两届不同,以当年通知为准。)
答题四大注意事项(每条都值分)
  1. 写过程的题别只写答案:中间步骤算分(网络流要列出每条增广路径及增量)。
  2. 2021 年旧大纲明确建议用文字而非程序答算法设计题:当年的考试不鼓励直接用 Java/C 代码代替算法描述;今年仍应以任课教师具体要求为准。用简明语言表达思想——例句:“用贪心算法:每次选择图中度数最大的点加入覆盖集……”该句仅示范“把算法步骤说清楚”的答题语言,不代表最大度数贪心是最小顶点覆盖的最优算法,也不能据此声称近似比。要得分仍须说明题目要求与正确性或近似性依据。
  3. 贪心证明用交换论证:设贪心解 S₁ 非最优;取与 S₁ 重合元素最多的最优解 S₂;比较第一个不同元素,把 S₂ 的换成 S₁ 的得 S₃——S₃ 仍最优且与 S₁ 重合更多,矛盾。故 S₁ 最优。(模板详见模块 2 §10)
  4. NPC 证明三段式:选已知 NPC 问题 A → 给出 A 实例到 B 实例的构造方法 → 证明归约正确性(iff)+ 多项式时间。(模板见 §4)
判断题专项清单(历年高频,README 已核勘误)
考点要点
归约方向A≤pB ⟹ B 不比 A 容易 √;NPC 证明是“已知 NPC ≤p 目标”;“A≤pB 且 A∈NPH ⟹ B∈NPH” √(B1 对、B2 错)
最大流最小割最大流值=最小割容量 √;最小割不一定唯一;增广路径可含反向边 √
近似算法近似比定义;多机调度 NP 完全故用贪心近似 √
0-1 背包 DPO(nC) 非多项式时间(伪多项式)√
区间相容按结束时间贪心最优 √;带权活动安排要 DP
P/NP/NPCNP≠“非P”;P⊆NP √;NPC∈NP √;“P≠NP 已被证明” ×
素数判定 / 并行(2018 秋)素数判定存在多项式算法(AKS 2002)√;并行不改变问题固有复杂度阶
大题六大套路
① 复杂度分析/渐近排序;② 分治递归式(Master/换元展开);③ DP 构造(填表+递推式+构造解);④ 贪心构造+正确性证明;⑤ 回溯/分支限界解空间树+剪枝+搜索过程;⑥ 网络流增广路径、NPC 归约证明、近似算法设计与比值证明。

9 · 一页纸总速查

四类P 多项式解;NP 多项式验;NPC = NP + 全员归约到它;NPH 只满足归约条件
归约A≤pB ⟹ B 不弱于 A;可传递;NPC 证明 = ∈NP + 已知NPC≤p目标
第一个 NPCCircuit-SAT(Cook 1971)
自身归约优化→判定:先判最小 k,再逐分量固定构造
网络流增广路径;最大流=最小割;Edmonds–Karp O(VE²);残量网络 s 可达集=最小割 S 侧
近似列表调度 2−1/m(t≤OPT、pⱼ≤OPT);顶点覆盖定价 2 倍(价格分摊);背包取整 (1−ε)
整数规划VC: minΣwx, xᵢ+xⱼ≥1;IS: maxΣx, xᵢ+xⱼ≤1;松弛 x∈[0,1]
答题写过程;算法≠程序;贪心=交换论证;NPC=构造+iff+多项式

冲刺路线(README 顺序):2021 大纲圈考点 → 模拟题1(中文计算)→ 2018 秋(有答案)→ B2 无答案 PDF 限时 → B1/C/A 查漏 → 判断题对照 B1/B2 差异表订正。祝考试顺利。

🎯 考场题型信号词 → 破题套路速查表 期末冲刺必背 · 信号词秒配定理与防扣分清单

考场上读题 10 秒内锁定“题干信号词”,直接调用中间列的定理模板作答,并在交卷前对照右列逐条排查高频扣分点。

🔍 题干信号词 / 设问特征 ⚡ 必用定理 / 核心递推式 / 标准破题套路 🚨 老师批改高频扣分点
区分优化问题与判定问题,辨析 P、NP、NPC、NPH 四大复杂性类关系 NP 定义为“非确定性图灵机多项式时间可解”等价于“确定性图灵机多项式时间可验证(给定证书 \(y\))”;\(\text{NPC} = \text{NP} \cap \text{NPH}\)(NPH 不必属于 NP,如停机问题或优化版 TSP) ⚠ 避坑:把 NP 翻译成“Non-Polynomial(非多项式时间)”——这是算法课期末第一大常识性零分雷区!
证明某判定问题 \(B\) 是 NP 完全问题(NPC 证明大题标准四步模板) 四步铁律:① 证 \(B\in\text{NP}\)(给出候选解/证书并说明可在多项式时间内验证合法性);② 选定一个已知的 NPC 问题 \(A\);③ 构造从 \(A\) 到 \(B\) 的多项式时间变换 \(f\)(注意方向必须是已知 NPC \(A \le_p B\)!);④ 双向证明 \(x\in A \iff f(x)\in B\) 并说明变换可在多项式时间内完成 ⚠ 避坑:归约方向写反(写成待证问题 \(B \le_p\) 已知 NPC 问题 \(A\),直接扣掉一半分!);或漏写第一步“证明 \(B\in\text{NP}\)”
默写大纲核心归约链及构造细节(3SAT → 团 → 顶点覆盖 → 子集和 → 0-1 背包) 熟记三大等价桥:图 \(G\) 有大小 \(k\) 的团 \(\iff\) 补图 \(\bar{G}\) 有大小 \(k\) 的独立集 \(\iff\) 补图 \(\bar{G}\) 有大小 \(|V|-k\) 的顶点覆盖;由判定问题多项式次调用构造优化解称为“自身归约(Self-reducibility)” ⚠ 避坑:团归约到顶点覆盖时,忘记对原图取补图 \(\bar{G}\),或者把目标规模 \(|V|-k\) 仍写成 \(k\)
容量网络求最大流与最小割 / 残留网络增广路演算 最大流最小割定理:最大流值 \(|f^*| = \min c(S,T)\)(注意割容量只算正向跨越 \(S\to T\) 的原图容量之和,不减反向容量!);残留网络中增广时正向残量减 \(\Delta\)、反向残量加 \(\Delta\)(退流机制) ⚠ 避坑:计算割容量 \(c(S,T)\) 时误把 \(T\to S\) 的边容量减掉了;或画残留网络漏画反向退流边导致找不到最后一条增广路
分析顶点覆盖、TSP(三角不等式)、多机调度的近似算法与近似比 \(\rho(n)\) 近似比定义 \(\rho(n)=\max\!\left(\frac{C}{C^*}, \frac{C^*}{C}\right)\ge 1\);证明套路:由于精确最优值 \(C^*\) 未知,必须先找一个易算的下界 \(LB \le C^*\)(如极大匹配边数 \(|M|\)、最小生成树权 \(w(T)\)、平均负载),再证算法解 \(C \le \rho\cdot LB \le \rho\cdot C^*\) ⚠ 避坑:TSP 若不满足三角不等式,则不存在具有常数近似比的多项式时间近似算法(除非 \(\text{P}=\text{NP}\)),答题时漏写“满足三角不等式”前提