图论第十、十一章精讲

北航 · 离散数学 2 · 第十章 图论 · 第十一章 图的基本问题

图论第十、十一章精讲

对应你上传的四份课件,从"图是什么"一直讲到第十一章的欧拉图和哈密顿图。每个概念按 定义原文 → 说人话 → 画出来 → 例题 的顺序讲,关键处有可以动手点的小实验。

整章只有一句话

这一章只研究一个对象:G = ⟨V, E⟩。V 是点的集合,E 是边的集合。后面所有概念(度、同构、子图、矩阵、通路)都是在问同一类问题:这两个集合之间满足什么条件。抓住这一点,几十个定义就不再是零散的名词。

怎么读课件里的逻辑式

课件几乎每个定义下面都有一行带 ∀ ∧ → ⇔ 的式子。那一行就是定义本身,比中文描述更精确。读法很固定:

符号读作例子
∀u∀v( … )对所有的 u、v,括号里都成立∀u∀v((u,v)∈E → u|v):只要 (u,v) 是边,u 和 v 就邻接
A → B如果 A,那么 B(u,v)∈E → u∈V ∧ v∈V:边的两个端点必须在点集里
A ⇔ BA 当且仅当 B(两者等价)Gs ⊆ G ⇔ Vs ⊆ V ∧ Es ⊆ E
|S|集合 S 的元素个数|V| = n 就是有 n 个点

课件里的 Python 代码也是同一个思路:V 用集合存点,E 用元组列表存边,isgraph(V,E) 就是把上面那条 "端点必须在点集里" 逐条边检查一遍。看代码时把它当成"定义的可执行版本"即可。

  1. 10.1引言七桥问题、复杂度,了解即可
  2. 10.2图、邻接与度握手定理是全章第一个核心工具
  3. 10.2同构怎样判断"两张图其实是一张"
  4. 10.3特殊图Kn、Cn、Wn、Km,n、Qn …
  5. 10.4子图与补图六种子图的区别,自补图,Turán
  6. 10.5矩阵表示Ak 数通路、可达矩阵、距离矩阵
  7. 10.6通路与回路简单/基本、连通、强/单向/弱
  8. 10.6分支、回路与非循环图竞赛图、W-过程、连通的充分条件
  9. 10.7割集与圈割点、桥、Tarjan 算法
  10. 10.8支配集、覆盖集、独立集极小与最小、匹配、点覆盖
  11. 11.2欧拉图一笔画、Fleury 算法、中国邮递员
  12. 11.2哈密顿图回溯搜索、Dirac 定理、充分条件
10.1

引言:为什么要学图

课件① 第 7–28 页

这部分是动机,考试一般不考细节,记住下面三件事就够了。

  1. 哥尼斯堡七桥问题(1736,欧拉):能否每座桥恰好走一次再回到家?把 4 块陆地当点、7 座桥当边,问题变成"图里有没有一条经过每条边恰好一次的回路"(欧拉回路)。结论:连通无向图有欧拉回路 ⇔ 每个点的度都是偶数。七桥图 4 个点的度是 5、3、3、3,全是奇数,所以走不成。这样判断只需看一遍所有点,复杂度 O(|V|);枚举 7 座桥的顺序要 7! = 5040 种。
  2. 哈密顿图问题:是否存在经过每个顶点恰好一次的回路?看起来只是把"边"换成"点",难度却天差地别:它是 NP 完全问题,目前没有已知的多项式算法。20 个点暴力枚举要 20! ≈ 2.4×1018 种排列。
  3. 复杂度分级:多项式 O(na) ≪ 指数 O(2n) ≪ 阶乘 O(n!)。后面讲"同构"时还会用到这个视角:判断同构如果去试所有点的对应方式,就是 O(n!)。

课件里 Google 图计算(Pregel)、图神经网络、知识图谱那几页,是在说明图模型的应用面,属于拓展阅读。

10.2

图的基本概念、邻接与度

课件① 第 29–53 页

无序偶与有序偶

一切从"两个点怎么配成一对"开始:

  • 无序偶 (x, y):不分先后,(a, b) = (b, a)。用来表示无向边。
  • 有序偶 ⟨x, y⟩:分先后,⟨a, b⟩ ≠ ⟨b, a⟩。用来表示有向边(从 x 指向 y)。
定义 10.2.1 · 10.2.2 无向图 / 有向图

设 V 是非空顶点集合,E 是边集合,则有序偶 G = ⟨V, E⟩ 称为图。E 由无序偶构成时叫无向图,由有序偶构成时叫有向图。

无向:E ⊆ {(x,y) | x∈V ∧ y∈V}  有向:E ⊆ {⟨x,y⟩ | x∈V ∧ y∈V}

注意 G = ⟨V, E⟩ 这个尖括号是"图这个整体是一个有序对(先写点集再写边集)",跟边是不是有向无关。

课件的无向图:V = {a,…,g},9 条边
g 不与任何点相连,是孤立点
课件的有向图:a、c、e 处有自环
a⇄e、d⇄e 是方向相反的两条边

必须分清的几个术语

术语意思
自环(环、自圈)两端是同一个点的边,如 (c, c)
平行边(多重边)两点之间不止一条边(有向图里要求方向也相同)
简单图既没有自环、也没有平行边的图。课件里很多定理(例如"必有两点度相同")只对简单图成立
孤立点不和任何边关联的点
(n, m) 图|V| = n,|E| = m。点数 n 叫图的阶(定义 10.2.3)
权图每条边带一个数(权值 w),边写成三元组 (w, u, v)(定义 10.2.4)。常用"权矩阵"存,不相连处记 ∞,自己到自己记 0
易错有向简单图里,⟨u,v⟩ 和 ⟨v,u⟩ 同时存在不算平行边,因为方向不同。所以有向简单图允许 "一对点之间来回各一条"。
课件的权图
W =

三种"挨着"的关系:邻接、关联、相邻

图里只有两种东西(点和边),两两配对就有三种关系,课件用同一个竖线符号 | 表示:

谁和谁名称条件记号
点 — 点邻接(定义 10.2.5)之间有边 (u,v)∈Eu | v
点 — 边关联(定义 10.2.6)点是这条边的端点u | e
边 — 边相邻(定义 10.2.7)两条不同的边共用一个端点e0 | e1
课件例图(v3 上有自环 c)

对照这张图:v1|v2(有边 a),v3|v3(自环 c 让 v3 和自己邻接);v2|f(v2 是 f 的端点);a|g(a、g 共用 v1),d|h(共用 v4)。

度:一个点"挂着"几条边

定义 10.2.8 无向图的度

无向图中与点 u 关联的边数叫 u 的度,记 d(u)。自环算 2 次。

上图里:d(v1)=2,d(v2)=4,d(v4)=3,d(v5)=2,而 d(v3)=5:边 g、b、d 各贡献 1,自环 c 贡献 2。

为什么自环要算 2把每条边想成两个"端头",度就是插在这个点上的端头个数。自环的两个端头都插在同一个点上,所以贡献 2。只有这样算,下面的握手定理才成立,课件第 50 页特意强调了这一点。
定义 10.2.9 有向图的入度、出度

以 u 为终点的边数叫入度 di(u)(i = in),以 u 为始点的边数叫出度 do(u)(o = out)。度 d(u) = di(u) + do(u)。

di(u) = |{v | ⟨v,u⟩∈E}|  do(u) = |{v | ⟨u,v⟩∈E}|
课件第 48 页:di(v3)=1(e2 指进来),do(v3)=2(e3、e4 指出去),d(v3)=3

握手定理

定理 10.2.1(握手定理)

设 G = ⟨V,E⟩ 是 (n, m) 图,则

∑u∈V d(u) = 2m

即:所有点的度加起来,等于边数的 2 倍。

一句话证明:每条边有 2 个端头,每个端头给某个点的度贡献 1。所有点的度之和就是在数端头总数,也就是 2m。名字的由来:一群人握手,每次握手两个人各记一次,所有人记的次数加起来必然是握手次数的两倍。

课件的归纳证明(对边数 m 归纳):m=1 时成立。假设 m=k 时成立,再加一条边 e,度数和增加 2,不管 e 是连接两个旧点、引入一个新点还是引入两个新点(课件分了 n′=n, n+1, n+2 三种情况),都有 2k + 2 = 2(k+1)。

三个立刻能用的推论
  1. 度为奇数的点有偶数个。因为总和 2m 是偶数,偶数度的点加起来是偶数,那奇数度点的度之和也必须是偶数,奇数个奇数相加是奇数,所以奇数度点只能有偶数个。
  2. 有向图:∑ di(u) = ∑ do(u) = m(每条边恰有一个起点、一个终点)。
  3. 给你一串"度数序列",先看和是不是偶数,奇数就直接不可能。例如 (3, 2, 2, 1, 1) 和为 9,不存在这样的图。
例 1(课件第 51 页)证明:节点数大于 1 的简单无向图中,必有两个结点的度相等。
展开解答(建议先自己想一分钟)

思路是抽屉原理:n 个点放进少于 n 个"度数抽屉",必有两个点落进同一个抽屉。

简单图里每个点最多和其余 n−1 个点相连,所以度只能取 0, 1, …, n−1,共 n 种值,正好等于点数,不能直接用抽屉原理。关键观察:0 和 n−1 不能同时出现。度为 n−1 的点和所有点相邻,那就不会有度为 0 的孤立点。分三种情况:

  1. 孤立点 ≥ 2 个:它们度都是 0,结论直接成立。
  2. 孤立点恰好 1 个:其余 n−1 个点不和它相连,最大度只能到 n−2,度取值范围 {1, …, n−2} 只有 n−2 种,n−1 个点放进 n−2 个抽屉,必有两个相同。
  3. 没有孤立点:度取值 {1, …, n−1},n−1 种值,n 个点,必有两个相同。
例 2(课件第 52 页)任意六个人中,若没有三个人彼此都认识,则必有三个人彼此都不认识。
展开解答

建模:6 个人是 6 个点,认识就连边。要证:图里没有三角形 ⇒ 有三个点两两不相邻。

盯住一个人 A,其余 5 人分成"A 认识的"和"A 不认识的"两组,必有一组 ≥ 3 人(5 个人分两组,抽屉原理)。

  1. A 认识至少 3 人,设为 C、D、E。如果 C、D、E 中有两人认识(比如 C、D),那 A、C、D 三人互相认识,与假设矛盾。所以 C、D、E 两两不认识,找到了。
  2. A 最多认识 2 人,则至少有 3 人与 A 不认识,设为 C、D、E。它们不可能两两都认识(否则是三角形),所以其中某两人(比如 C、D)不认识,于是 A、C、D 两两不认识。

这就是 Ramsey 数 R(3,3)=6 的证明:6 个点的任意图,要么自己有三角形,要么补图有三角形。

例 3(课件第 53 页)唐氏夫妇邀请另外三对夫妇吃饭。每个人不和自己、不和配偶握手,任意两人最多握一次。饭后唐先生问其余每个人握了几次手,7 个人的回答都不相同。唐太太握了几次?
展开解答

一共 8 人。每人最多和 6 人握手(排除自己和配偶),所以答案只能在 0~6 之间。唐先生问了 7 个人,7 个不同的答案只能恰好是 0, 1, 2, 3, 4, 5, 6。

  1. 握 6 次的人和除配偶以外的所有人都握了手。那么除了他的配偶,每个人至少握过 1 次。所以握 0 次的人只能是他的配偶:(6, 0) 是一对夫妇。
  2. 把这对夫妇拿掉,剩下每个人的次数都减 1(每人都和"6"握过、都没和"0"握过)。剩下的人回答变成 0,1,2,3,4(对应原来 1~5),同样的推理得 (5, 1) 是一对。
  3. 再拿掉,得 (4, 2) 是一对。
  4. 只剩回答 3 的人,他的配偶不在被问的 7 人中,只能是唐先生本人。所以回答 3 的是唐太太。

答:唐太太握了 3 次手。

10.2

同构:两张图其实是同一张

课件① 第 54–73 页

定义 10.2.10(同构 isomorphism)

设无向图 G = ⟨V,E⟩ 和 G′ = ⟨V′,E′⟩,如果存在双射 f : V → V′,使得

(ui, uj) ∈ E ⇔ (f(ui), f(uj)) ∈ E′

则称 G 与 G′ 同构,记 G ≅ G′。

说人话

把 G 的每个点改个名字(f 就是改名规则,一个对一个,不能两个点改成同一个名字,也不能漏),改完之后边集和 G′ 一模一样。至于两张图在纸上画成什么形状,完全不重要。

定义里的"当且仅当"两个方向都要:原来有边的改名后还有边,原来没边的改名后也没边。

G:一个正方形
H:看起来像个"蝴蝶结"

课件第 54 页给的双射:u1→v1,u2→v4,u4→v2,u3→v3。逐条验证 G 的 4 条边:

G 的边改名后在 H 中?
(u1,u2)(v1,v4)✓
(u2,u4)(v4,v2)✓
(u4,u3)(v2,v3)✓
(u3,u1)(v3,v1)✓

两边都是 4 条边,G 的边全部映到了 H 的边,H 也没有多出来的边,所以"⇔"两个方向都满足,G ≅ H。把 H 的 v3、v4 左右交换一下重画,它就是正方形。

有向图的同构(课件第 62 页)同理,只是还要保持方向:⟨u,v⟩∈E ⇔ ⟨f(u),f(v)⟩∈E′。

怎么判断同构:必要条件只能用来"否定"

直接按定义找双射,最坏要试 n! 种对应,太慢。课件说,目前没有"简单而充分"的判定条件,但有一组必要条件。同构的两张图必须满足:

  1. 点数相同;
  2. 边数相同;
  3. 度数序列相同(度数相同的点个数相同)。而且同构映射一定把 k 度点映到 k 度点。

还可以继续加:两个 3 度点相邻吗?有没有三角形?有几个连通块?这些"图的不变量"在同构下都不会变。

逻辑方向别弄反

必要条件的用法是:只要有一条不满足 ⇒ 一定不同构。反过来,全都满足 不能推出同构。例如六边形 C6 和两个分开的三角形:都是 6 点 6 边、每点度都是 2,但前者连通、后者不连通,不同构。要证明同构,必须把双射写出来并验证。

例 4(课件第 57 页)判断 G 与 H 是否同构。
G
H
展开解答

两者都是 5 个点、6 条边,前两个条件都满足,接着比度数序列:

  • G:a=2, b=2, c=3, d=2, e=3 → 排序后 (3,3,2,2,2)
  • H:a=4, b=2, c=3, d=2, e=1 → 排序后 (4,3,2,2,1)

度数序列不同,所以 不同构。(课件第 57 页 H 的边集文字少写了 (a,d),按图应有 6 条边;就算按 5 条边算,边数不同也直接不同构。)

例 5(课件第 58 页)图①是六边形加三条"长对角线"(1-4、2-5、3-6),图③是一个三角形外套一个三角形、对应顶点相连(三棱柱)。它们同构吗?
展开解答

两张图都是 6 点 9 边,每个点度都是 3,三条必要条件全部满足,光看这些判不出来。

换一个不变量:三角形。图③里本来就有三角形;图①中,把 1、3、5 放一组,2、4、6 放一组,会发现每条边都连接两组之间(它其实是 K3,3),组内没有边,所以不可能有三角形(三角形必有两个点在同一组)。有三角形的图和没有三角形的图不可能同构,所以 ① ≇ ③。图② 也是 K3,3 的另一种画法,① ≅ ②。

思考题(课件第 63–67 页)(1) 画出 4 阶 3 条边的所有非同构无向简单图;(2) 画出 3 阶 2 条边的所有非同构有向简单图。
展开解答

(1) 先用握手定理限制度数序列:4 个点度数和为 2×3=6,简单图每个点度 ≤ 3,奇数度的点有偶数个。把 6 拆成 4 个这样的数,只有三种:

3,1,1,1(星)
2,2,1,1(路)
2,2,2,0(三角形+孤立点)

每种度数序列恰好只有一种画法,所以一共 3 个。课件追问的 (3,3,0,0) 为什么不行:简单图中度为 3 的点要和另外 3 个点全部相邻,两个这样的点会让其余两个点度数至少为 2,不可能是 0。

(2) 3 个点、2 条有向边,总度数 4,每点出度、入度都 ≤ 2。按"两条边的位置关系"分类:

首尾相接 b→a→c
都指进 a
都从 a 出
一对来回 + 孤立点

前三个度数序列都是 (2,1,1),但入度、出度的分布不同(课件写的入度列 0,1,1;0,2,0;1,0,1),所以互不同构;第四个度数序列是 (2,2,0)。共 4 个。

同胚与同态(了解)

同胚(定义 10.2.11):如果 G′ 是在 G 的边上"插入若干新点"(把一条边 (u,v) 换成一条路 u–w0–…–v)得到的,就称 G′ 是 G 的同胚图。插入的点度都是 2,图的"形状骨架"没变。这个概念后面判断平面图时会用到。

同态(扩展):比同构宽松,只要求有函数 f : V→V′ 把边映成边,不要求一一对应,允许多个点合并成一个。课件例子里 x3、x4 都映到 y3。

Weisfeiler–Lehman 算法:给点"上色"来比较

课件介绍了一个实用的同构检验思路。不去试所有对应方式,而是反复给点重新上色:

  1. 开始时所有点同一种颜色。
  2. 每一轮,每个点看"自己的颜色 + 所有邻居颜色组成的多重集",相同的组合给同一个新颜色。第一轮之后颜色其实就等于度数。
  3. 每轮比较两张图各颜色的点数。只要某一轮对不上,一定不同构;颜色不再细分且两边一直一样,就判"可能同构"。

它的弱点正好是课件说的正则图:每个点度数相同,邻居颜色也相同,颜色永远不会分开。下面可以亲手试:

WL 上色实验

选一对图,点"下一轮",看颜色怎么细分。点旁边的数字是颜色编号。

补充:图同构问题目前既不知道是否属于 P,也不知道是否 NP 完全。Babai 在 2015 年给出了拟多项式时间 2(log n)k 的算法。而"子图同构"(判断 G 里是否含有一个和 H 同构的子图)已被证明是 NP 完全的。

10.3

特殊图

课件① 第 75–109 页

这些图之所以"特殊",是因为它们的边有清楚的规律,点数、边数、度数都能直接写出公式。学的时候把三个量对上就行:几个点、几条边、每个点几度,边数都可以用握手定理(度数和 ÷ 2)验算。

平凡图与完全图

定义 10.3.1 孤立点、平凡图不与任何点相连的点叫孤立点,只由一个孤立点构成的图叫平凡图。
定义 10.3.2 完全图 Kn

n ≥ 2 的简单图,任意两个不同顶点之间恰有一条边。

∀u∀v(u∈V ∧ v∈V ∧ u≠v → (u,v)∈E)
K3
K4
K5
K6

每个点和其他 n−1 个点相连,所以 Kn 是 (n−1) 次正则图,边数 n(n−1)/2(握手:n·(n−1) = 2m)。这也是 n 阶简单图边数的上限。课件第 99–101 页的计时表说明:Kn 的边数随 n 平方增长,n = 5000 时已有约 1250 万条边。

圈图与轮图

定义 10.3.3 圈图 Cnn 个顶点恰好连成一个圈的简单图(n ≥ 3)。
E = {(vi, vi+1) | i = 0,…,n−2} ∪ {(vn−1, v0)}
定义 10.3.4 轮图 Wnn−1 个顶点构成圈图,再加一个中心点与圈上每个顶点相连。
C4
C6
W5(课件记法)
W7(课件记法)

Cn:n 点、n 边,2 次正则。Wn(课件记法,共 n 个点):圈上 n−1 条边 + 辐条 n−1 条,共 2(n−1) 条边;圈上的点度为 3,中心点度为 n−1。

下标约定要看清按课件定义和构建表(第 84 页),W4 有 4 个点,就是 K4。但课件第 83 页的配图取自 Rosen 教材,那里 Wn 的 n 指"圈上的点数",共 n+1 个点(图下标 W3 实际画了 4 个点)。做题时以题目给的定义为准,拿不准就把点数写清楚。

二部图(偶图)与完全二部图

定义 10.3.5 二部图

无向图 G 的点集能分成两部分 V = V1 ∪ V2,V1 ∩ V2 = ∅,使得每条边的一端在 V1、另一端在 V2。记作 G = (V1, V2; E)。

定义 10.3.6 完全二部图 Km,n两部分分别有 m 和 n 个点,并且每个点与另一部分的所有点都相连。
K2,3
K3,3
K3,5

Km,n:m+n 个点,mn 条边;左边每点度 n,右边每点度 m(验算:mn + nm = 2mn)。

直觉二部图就是"能用两种颜色给点涂色,使每条边两端颜色不同"的图。沿着任何回路走,颜色交替变化,回到起点必须走偶数步,所以二部图没有奇数长的回路。反过来也成立,10.5 节会用邻接矩阵证明这件事。

n 立方体图 Qn

定义 10.3.8顶点是所有 n 位二进制串(共 2n 个),两个串恰好有一位不同就连边。
Q1
Q2
Q3(立方体)

每个串有 n 位,翻转任意一位都得到一个邻居,所以 Qn 是 n 次正则图,边数 n·2n/2 = n·2n−1(Q3:12 条)。它还是二部图:按"1 的个数是奇数还是偶数"分两组,翻一位一定改变奇偶性。

0-1 序列图 Sn(De Bruijn 图)

定义 10.3.7

有 N = 2m 个点,编号 0, …, N−1。对每个 i,令 j = (2i) % N,k = (2i+1) % N,则 ⟨vi, vj⟩ 和 ⟨vi, vk⟩ 都是边。这是有向图。

S2:4 个点,8 条边
看懂公式的关键

把编号写成 m 位二进制,2i % N 就是"整体左移一位,丢掉最高位,末尾补 0",(2i+1) % N 是末尾补 1。例如 m=3 时 101 → 010 或 011。

所以边 u → v 意味着"u 的后 m−1 位 = v 的前 m−1 位",一条边恰好对应一个 m+1 位串(课件第 89 页:边 ak 用 4 位二进制表示,前 3 位是起点,后 3 位是终点)。每个点出度 2、入度 2,共 2m+1 条边。

r 次正则图与彼德森图

定义 10.3.9 r 次正则图所有点的度都等于常数 r。
∀v ∈ V → d(v) = r

已经见过的:Kn 是 (n−1) 正则,Cn 是 2 正则,Qn 是 n 正则,Kn,n 是 n 正则。彼德森图是 10 个点、15 条边的 3 次正则图(外五边形 + 内五角星 + 5 条连线),是图论里最常用的反例。

彼德森图(课件第 95 页的边集)
r 正则图存在的两个条件(做题必用)

n 阶 r 正则简单图要存在,必须:

  1. r ≤ n−1(最多和其余所有点相连);
  2. n·r 是偶数(握手定理:nr = 2m)。

满足这两条时一定能构造出来。

例 6(课件第 94、127–130 页)(1) 设七阶无向简单图 G 为 k-正则图,k = 4, 5, 6, 7 中哪些不成立?(2) 换成六阶呢?六阶 4-正则图有几个?
展开解答

(1) n = 7:k=5 时 7×5=35 是奇数,违反握手定理;k=7 时 7 > 6,超过上限。B、D 不成立。k=4 可以(C7 的补图),k=6 就是 K7。

(2) n = 6:6k 总是偶数,只看上限 k ≤ 5。k=4 可以,k=5 是 K6,C、D 不成立。

六阶 4-正则图有几个?看它的补图:每个点在 K6 里度为 5,删掉 4 条后剩 1,补图是 1-正则图,也就是 3 条互不相交的边(完美匹配)。课件第 129 页正是从 K6 中删掉三条互不相交的红边。不管删哪 3 条,得到的图都同构(都是八面体图),所以在同构意义下只有 1 个。如果顶点带标号、算不同的边集,则有 5×3×1 = 15 种。

10.4

子图、补图

课件① 第 111–134 页

六个定义,全部都是在 Vs、Es 上加不同的条件。先看总表,再逐个看。

名称点集条件边集条件一句话
子图 Gs ⊆ GVs ⊆ VEs ⊆ E拿一部分点、一部分边(边的端点要在 Vs 里)
真子图 Gs ⊂ GGs ⊆ G,且 Vs ⊂ V 或 Es ⊂ E至少少了点什么,不能是 G 本身
生成子图Vs = VEs ⊆ E点一个不少,只删边
导出子图 G[Vs]Vs ⊆ VVs 内部的边全部保留只选点,边被点"导出"
补图 ~GVE(Kn) − E原来没有的边都连上,原来有的都去掉
相对补图 G − G1E2 的端点E − E1从 G 里拿掉 G1 的边
定义 10.4.1–10.4.2 子图、真子图

若 Vs ⊆ V 并且 Es ⊆ E,称 Gs 是 G 的子图。若再满足 Vs ⊂ V 或 Es ⊂ E(真包含),称为真子图。

Gs ⊆ G ⇔ Vs ⊆ V ∧ Es ⊆ E  Gs ⊂ G ⇔ Gs ⊆ G ∧ (Vs ⊂ V ∨ Es ⊂ E)

隐含要求:Gs 自己也得是个图,所以 Es 里每条边的端点都要在 Vs 中。不能删掉一个点却留下连着它的边。

定义 10.4.3 生成子图(spanning subgraph)子图并且 Vs = V。
Gs ⊆ G ∧ Vs = V
定义 10.4.4 导出子图(induced subgraph)

选定点集 Vs ⊆ V,边集取 E 中两端都在 Vs 里的所有边,得到的子图叫 Vs 导出的子图。

Es = {(u,v) | u∈Vs ∧ v∈Vs ∧ (u,v)∈E}

课件第 116 页的式子写成了 "v ∈ Es",应为 v ∈ Vs,是笔误。

生成子图 vs 导出子图生成子图:点全要,边随便删。导出子图:点随便选,选中的点之间的边一条都不能删。一个子图可以两者都是(G 本身),也可以两者都不是(比如删掉一个点,再额外删一条剩余点之间的边)。
定义 10.4.5 补图

G 为 n 阶无向简单图。以 V 为点集,以"使 G 成为完全图 Kn 需要添加的边"为边集,得到的图叫 G 的补图,记 ~G(也常写 Ḡ)。

直接推论:|E(G)| + |E(~G)| = n(n−1)/2;dG(v) + d~G(v) = n−1。

定义 10.4.6 相对补图

G1、G2 都是 G 的子图,若 E2 = E − E1,且 V2 是 E2 中边关联的点的集合,则称 G2 是 G1 相对于 G 的补图,记 G2 = G − G1。

补图是"相对于 Kn"的特例,相对补图把 Kn 换成任意的 G。注意 V2 只保留还连着边的点。

子图实验

点击顶点或边来选取 Vs、Es,右边实时判断它属于哪几类子图。选一条边会自动选上它的两个端点;取消一个点会顺带取消连着它的边。

已选的边未选的边补图的边
例 7(课件第 131–133 页)与自己的补图同构的简单无向图叫自补图。证明:自补图的阶 n 满足 n ≡ 0 或 1 (mod 4)。
解答

G 与 ~G 合起来正好是 Kn,所以 |E(G)| + |E(~G)| = n(n−1)/2。同构的图边数相同,因此

|E(G)| = |E(~G)| = n(n−1)/4

边数是整数,所以 4 | n(n−1)。n 和 n−1 是相邻整数,一奇一偶,奇数那个不含因子 2,所以 4 必须整个整除偶数那个:4 | n 或 4 | n−1,即 n = 4i 或 n = 4i+1。

例子:4 阶的路 P4,5 阶的 C5(课件第 133 页把 K5 拆成五边形和五角星,两者都是 C5)。

P4:a-b-c-d
补图:c-a-d-b,还是一条路
C5
C5 的补图:五角星

注意这只是必要条件:n=4、5 存在自补图,并不是说所有 4 阶图都是自补图。

例 8(课件第 134 页,Turán 定理的特例)证明:不含三角形(K3)的 n 阶简单无向图最多有 ⌊n²/4⌋ 条边。
解答

对 n 做数学归纳。n ≤ 3 时直接验证(n=3 最多 2 条边,⌊9/4⌋=2)。设 n = k 时成立,看 n = k+1 的无三角形图 G。

第一步:G 里一定有一个点的度 ≤ ⌊(k+1)/2⌋。(课件直接用了这个结论,这里补上理由。)反证:假设所有点的度都 > (k+1)/2。任取一条边 (u,v),则 d(u) + d(v) > k+1,而 u、v 的邻居都在这 k+1 个点里,由抽屉原理 u 和 v 必有公共邻居 w,于是 u、v、w 构成三角形,矛盾。

第二步:删掉这个点 x,剩下 k 阶图仍无三角形,由归纳假设最多 ⌊k²/4⌋ 条边,再加回 x 的边:

  • k 偶数:k²/4 + k/2 = (k²+2k)/4 = ⌊(k+1)²/4⌋
  • k 奇数:(k²−1)/4 + (k+1)/2 = (k+1)²/4

两种情况都 ≤ ⌊(k+1)²/4⌋,结论成立。

上界能取到:完全二部图 K⌊n/2⌋,⌈n/2⌉ 没有三角形(二部图无奇圈),边数正好 ⌊n/2⌋·⌈n/2⌉ = ⌊n²/4⌋。

10.5

图的矩阵表示

课件① 第 136–151 页,课件② 第 1–14 页

把图写成矩阵有两个好处:计算机能存,也能用矩阵运算回答图的问题(两点之间有几条长度为 k 的通路?谁能到达谁?最短距离是多少?)。这一节的主线是:邻接矩阵 A → Ak → 可达矩阵 R → 距离矩阵 D。

先说存储:为什么需要稀疏格式

邻接矩阵是 n×n 的。100 万个点就是 1012 个元素,每个按 int64 占 8 字节,约 8×1012 字节 ≈ 7.28 TB。可真实网络很稀疏,绝大多数元素是 0,所以只存非零元素。课件第 142–144 页用下面这个矩阵演示了三种格式:

M =
格式数组说明
COOvalue  =[1 1 2 3 1 4 2]
row    =[0 0 1 2 2 3 3]
column =[0 2 2 0 1 1 3]
每个非零元素记 (行, 列, 值) 三元组,最直观
CSRvalue  =[1 1 2 3 1 4 2]
column =[0 2 2 0 1 1 3]
row_ptr=[0 2 3 5 7]
按行存。row_ptr[i] 到 row_ptr[i+1] 是第 i 行的元素在 value 中的范围,例如第 2 行是下标 3、4,即值 3、1
CSCvalue  =[1 3 1 4 1 2 2]
row    =[0 2 2 3 0 1 3]
col_ptr=[0 2 4 6 7]
按列存,与 CSR 对称。元素要按列重新排序

课件把 CSR 的行指针也叫 row_index,容易和 COO 的 row 混淆,看长度区分:指针数组长度是"行数+1"。课件第 144 页手写的 CSC 中 value 和 row 两行与 COO 相同,没有按列重排;按列重排后应是上表的结果,可以自己逐列读一遍验证。图的"邻接表"(课件第 141 页的数组 + 链表)本质上和 CSR 是一回事。

关联矩阵:点 × 边

定义 10.5.1 无向图的关联矩阵

简单无向图,|V|=n,|E|=m。n×m 矩阵 A = [aij]:点 vi 是边 ej 的端点,则 aij = 1,否则为 0。

课件第 146 页

读法:每一列恰有两个 1(一条边两个端点);每一行的和是这个点的度。所有元素之和 = 2m,这就是握手定理的矩阵版。

定义 10.5.2 有向图的关联矩阵

边 ej 从 ui 出发,aij = 1;ej 指向 ui,aij = −1;否则 0。

课件第 147 页

读法:每列恰好一个 1、一个 −1,列和为 0;某一行中 1 的个数是出度,−1 的个数是入度。例如 d 行:1 出现 3 次(e4、e5、e6 从 d 出发),−1 出现 1 次(e3 指向 d)。

邻接矩阵:点 × 点

定义 10.5.3 邻接矩阵

n×n 矩阵 A = [aij],(vi, vj) ∈ E 则 aij = 1,否则 0。有向图用 ⟨vi, vj⟩,第 i 行第 j 列表示 从 i 指向 j。有平行边时 aij 记边的条数,有自环时对角线非 0。

无向简单图(第 148 页)
多重边 + 自环(第 149 页)
有向图(第 150 页)

从邻接矩阵能直接读出什么(课件② 第 6–7 页)

  1. 无向图的 A 是对称矩阵;有向图一般不对称。
  2. 没有平行边 ⇔ 元素只有 0 和 1;有自环 ⇔ 对角线有非 0 元素;简单图 ⇔ 只有 0、1 且对角线全 0;零图(没有边)⇔ A 是零矩阵。
  3. 无向图:d(vi) = 2aii + ∑j≠i aij(自环算两次)。简单图就是"第 i 行之和"。
  4. 有向图:第 i 行之和 = 出度,第 i 列之和 = 入度。
  5. 图有 k 个连通分支 ⇔ 适当重排点的顺序后,A 变成分块对角矩阵,每块是一个分支自己的邻接矩阵。
两个分支
原顺序
重排为 v1 v3 | v2 v4 v5

核心:Ak 在数通路

最重要的一个事实

(Ak)ij = 从 vi 到 vj 长度为 k 的通路条数(长度 = 经过的边数,点和边都可以重复)。

为什么?看 k = 2:

(A²)ij = ∑t ait · atj

乘积 ait·atj 等于 1 恰好当 i→t 和 t→j 两条边都存在,也就是"走两步、中间经过 t"。对所有中间点 t 求和,就是长度 2 的通路总数。同理 Ak = Ak−1·A:先用 k−1 步到某个 t,再走一步到 j,归纳即得。

例:路 a – b – c。

A =
A² =
A³ =

(A²)bb = 2:b→a→b 和 b→c→b。(A²)ac = 1:a→b→c。(A²)ab = 0:a 到 b 没法恰好走 2 步。简单无向图里 (A²)ii = d(vi),因为每个邻居都提供一条"去了就回"的长度 2 通路。

可达矩阵

定义 10.5.4 指示矩阵(布尔化)

B(A):把 A 中所有非 0 元素改成 1,0 不变。只关心"有没有",不关心"有几个"。

定义 10.5.5 可达矩阵
R = B(I + A + A² + ⋯ + An−1)

rij = 1 表示 vi 可以到达 vj。

逐项理解:

  • Ak 的 (i,j) 非 0 ⇔ 存在长度恰好为 k 的通路。把 k = 0, 1, …, n−1 加起来,非 0 就说明"存在某个长度的通路",即可达。
  • 为什么有 I:I = A0,代表走 0 步,规定每个点可达自己(课件② 第 12 页 R(v1) 里包含 v1 自己)。
  • 为什么只加到 n−1:10.6 节的定理 10.6.1 会证明,如果 u 能到 v,一定有一条长度 ≤ n−1 的通路(不重复经过点的通路最多 n 个点、n−1 条边)。更长的项不会带来新的"可达"信息。
定理 10.5.1
R = B(I + A + ⋯ + An−1) = B[(I + A)n−1]

证明:I 与任何矩阵都可交换(IA = AI = A),所以二项式定理对 I + A 成立:

(I + A)n−1 = ∑i=0n−1 Cn−1i Ai

所有组合数 Cn−1i ≥ 1,A 的元素又都非负,所以右边第 (j,k) 个元素非 0 ⇔ 某个 aijk ≠ 0 ⇔ I + A + ⋯ + An−1 的第 (j,k) 个元素非 0。布尔化后相等。∎

课件里"矩阵乘法不满足交换律"那页是想说什么

一般矩阵 (A+B)² = A² + AB + BA + B²,只有 AB = BA 时才能合并成 A² + 2AB + B²,二项式定理才能用。课件第 2 页黄框里 "(A+B)n = ∑CniAiBn−i?" 打问号就是这个原因。这里能用,是因为其中一个是单位矩阵 I。课件用归纳法把这个二项式展开重新证了一遍。

另外,课件 Python 里 R=(I+A)**(n-1) 输出的是 [[42, 18, 44 …]] 这样的大数,那是还没布尔化的 (I+A)n−1,非 0 即可达,套一层 B(·) 才是可达矩阵。

还有一处容易看漏:课件第 5 页调用的是 reachabilitymatrix(A,8,2),第三个参数 n 传的是 2,所以算的是 B[(I+A)1],只反映"一步以内能到"。对照输出可以验证:R 的第 0 行 [1,1,1,0,…] 和 I+A 的第 0 行完全一样。要得到真正的可达矩阵,n 应该传点数 8。

距离矩阵

定义 距离、直径、距离矩阵

从 v1 可达 v2 时,最短通路的长度叫距离 d(v1, v2);不可达时 d = ∞(约定 ∞+∞=∞,n+∞=∞)。图的直径 = 所有点对距离的最大值。距离矩阵 D = (dij),dij = d(vi, vj)。

定理 由邻接矩阵求距离矩阵
dij = min{ k | 0 ≤ k < n ∧ akij > 0 },若所有 akij = 0 则 dij = ∞

说人话:依次算 A0, A1, A2, …,第一次在 (i,j) 处变成非 0 的那个幂次就是距离。

直径的直观意义:六度分隔(课件③ 第 13 页)

"你和任何一个陌生人之间所间隔的人不会超过六个",用图论的话说就是:把人当点、认识当边,这张社交网络的直径大约是 6。1967 年 Milgram 的连锁信实验、2001 年 Watts 的电子邮件实验(6 万多名志愿者、18 个目标)都发现消息平均经过 5~7 人就能送到。课件第 11 页列的几个真实网络的直径(美国公路网 617、欧洲公路网 62、DBpedia 12、Twitter 8)也说明:社交类网络点很多,直径却很小。

有向图的距离不对称无向图中 d(u,v) = d(v,u);有向图中可能不同。课件② 第 12 页:d(v1,v2) = 1,d(v2,v1) = 2,d(v5,v6) = ∞。把它看作无向图时直径是 4(比如 v6–v5–v4–v3–v1)。下面的实验室里选"距离矩阵例题"可以看到完整的 D。

矩阵实验室

左边点格子编辑邻接矩阵(无向图会自动对称;对角线 = 自环),右边自动算出度数、Ak、可达矩阵、距离矩阵和连通性。点击 Ak 里的任意数字,会列出对应的那几条通路。

邻接矩阵 A(点击编辑)

度数

判断

A 的 k 次幂

点击上面矩阵里的一个数,列出对应的通路

可达矩阵 R = B(I + A + ⋯ + An−1)

看未布尔化的 (I+A)n−1(课件 Python 输出的就是它)

距离矩阵 D

二部图与邻接矩阵(课件② 第 8–9 页)

题目

设 G 是 n 个点的简单无向图,邻接矩阵为 A。证明:G 是二部图 ⇔ 对任意奇数 k,Ak 的对角线元素全为 0(即 G 没有奇数长的回路)。

(⇒) G 是二部图,点分成 V1、V2,每条边跨两边。从点 i 出发,每走一步就换一边。若 i ∈ V1,走奇数步后一定在 V2,不可能回到 i;i ∈ V2 同理。所以 k 为奇数时从 i 回到 i 的长度 k 通路条数为 0,即 Ak[i,i] = 0。

(⇐) 假设所有奇数 k 都有 Ak[i,i] = 0,即没有奇数长的闭通路。先看一个连通分支,任取其中一点 v,令

  • Vo:从 v 出发能用奇数步到达的点
  • Ve:能用偶数步到达的点
  1. 两者不相交:若某点 u 既能奇数步到、又能偶数步到,把"v 奇数步到 u"和"u 偶数步返回 v"(无向图可以原路倒着走)接起来,就是一条从 v 回到 v 的奇数长闭通路,矛盾。
  2. 两者覆盖整个分支:分支连通,每个点都能从 v 到达,步数不是奇就是偶。
  3. 每条边跨两边:若边 (x,y) 两端都在 Ve,则到 x 偶数步、再走一步到 y 就是奇数步,y 同时属于 Vo,与 1 矛盾。两端都在 Vo 同理。

每个分支都这样分好,再合并,就得到整张图的二分,所以 G 是二部图。∎

实际判断时只需检查 k = 1, 3, 5, … 到 n 为止:如果有奇数长的闭通路,就一定有长度 ≤ n 的奇数圈。实验室里的"二部图"判断就是这样算的,可以选 C6 和 C5 对比。

10.6

通路和回路

课件② 第 16–38 页

通路、简单通路、基本通路

定义 10.6.1(通路 path)

若 uk ∈ V,(uk, uk+1) ∈ E,k = 0, 1, …, n−1,则称点 u0 与 un 之间存在通路,记 u0 ⇒ un。通路的长度是边数 n。

课件的递归写法:(1) 每条边本身是通路;(2) 若 (u0, …, un−1) 是通路且 (un−1, un) ∈ E,则在末尾接上 un 仍是通路。

说人话:沿着边一步一步走出来的点序列就是通路,点和边都允许重复。

定义 10.6.2 · 10.6.3

简单通路:每条边最多出现一次。
基本通路:每个顶点最多出现一次。

简单:∀ei∀ej(ei, ej 是通路上不同位置的边 → ei ≠ ej) 基本:把边换成点

关系:基本通路一定是简单通路(点不重复,边自然不重复:边重复意味着它的端点也重复)。反过来不对。

术语对照(换教材时最容易乱)
本课件点重复?边重复?英文常用屈婉玲版教材
通路可以可以walk通路
简单通路可以不可以trail简单通路
基本通路不可以不可以path初级通路(路径)

课件把定义 10.6.1 叫 "path",但它允许重复,对应的是英文的 walk。做题按本课程的叫法。

通路判定器

在课件第 21 页这张图上输入一串顶点(空格分隔),自动判断它是不是通路、长度多少、是简单还是基本、是否是回路。

定理 10.6.1

G 是 n 阶图。若顶点 u、v 之间存在通路,则存在长度 ≤ n−1 的通路。

证明:设通路为 u = u1 ⇒ u2 ⇒ ⋯ ⇒ um = v。如果它已经足够短就结束。否则它上面的点比 n 个多,由鸽笼原理必有 i < j 使 ui = uj(同一个点出现两次)。把中间绕的那一圈 ui+1, …, uj 剪掉:

u = u1 ⇒ ⋯ ⇒ ui−1 ⇒ ui ⇒ uj+1 ⇒ ⋯ ⇒ um = v

仍是从 u 到 v 的通路,而且更短。反复剪,直到没有重复点为止。此时这是一条基本通路,至多 n 个不同的点,所以至多 n−1 条边。∎

这条定理的两个用处
  1. 可达 ⇔ 存在基本通路(课件② 第 10 页的定理)。判断能否到达,只需要找不重复点的路。
  2. 它就是可达矩阵只加到 An−1 的理由。

回路

定义 10.6.5–10.6.7

回路:从 u 出发并回到 u 的通路,记 u ⇒ u。
简单回路:边不重复的回路。
基本回路:除起点终点重合外,点不重复的回路(就是"圈")。

定义 10.6.4 · 10.6.8 完备通路、完备回路

经过有向图中所有节点的一条通路(回路),称为完备通路(完备回路)。只要求每个点至少经过一次,允许重复。

无向图的连通

定义 10.6.9 · 10.6.10

无向图中 u、v 之间存在通路,称 u 和 v 连通。任意两个点都连通的图叫连通图,否则是非连通图。连通关系把点集分成若干块,每块叫一个连通分支。

定义 10.6.11 · 10.6.12 割点、桥

连通无向图中,删掉一个点(及它关联的边)后不再连通,这个点叫割点。删掉一条边后不再连通,这条边叫割边或桥。

课件第 25 页:高亮的边 (c,e) 是桥,c、e 是割点

直觉:桥是"唯一的通道"。一条边在某个回路上,删掉它还能绕回路另一侧走,就不是桥。所以一条边是桥 ⇔ 它不在任何回路上。

有向图的三种连通

基础图把有向图的每条边都去掉方向得到的无向图 G1 = ⟨V, E1⟩,E1 = {(u,v) | ⟨u,v⟩ ∈ E}。
名称条件(对每一对点 u、v)定义
强连通u ⇒ v 并且 v ⇒ u10.6.14
单向连通u ⇒ v 或者 v ⇒ u(至少一个方向能到)10.6.15
弱连通基础图是连通的(忽略方向能连上)10.6.16
不连通连弱连通都不是10.6.17
强连通:沿着圈谁都能到谁
单向连通:a→b→c→d 一条线全部串起;但 d 回不到 a
弱连通:b、d 都是"死胡同",b 和 d 互相到不了

强连通 ⇒ 单向连通 ⇒ 弱连通,反方向都不成立(上面后两个图就是反例)。判断时从强往弱试:先看能不能两两互达,再看任意两点是不是至少一个方向能到,最后忽略方向看连不连通。在矩阵实验室里勾选"有向图",判断栏会给出这个结论。

两个定理:用"一条通路"刻画连通性

定理 10.6.2有向图 G 是强连通的 ⇔ G 有一条完备回路。
定理 10.6.3有向图 G 是单向连通的 ⇔ G 有一条完备通路。

容易的方向(⇐):有完备通路 w1 ⇒ w2 ⇒ ⋯ ⇒ wt,所有点都在上面。任取两点 u、v,它们在通路上一前一后,前面的沿着通路就能走到后面的,所以至少一个方向可达,G 单向连通。完备回路的情况更强:沿回路绕一圈,谁都能到谁,所以强连通。

强连通 ⇒ 完备回路:把点排成 v1, v2, …, vn,强连通保证每段 vi ⇒ vi+1 和最后 vn ⇒ v1 都有通路,首尾接起来就是一条经过所有点的回路。

单向连通 ⇒ 完备通路(难点):这里不能随便排顺序,因为 vi 不一定能到 vi+1。课件第 30–38 页用的是对点数归纳 + 插入的思路:

  1. 假设除 v 以外的点已经串成一条通路 v1 ⇒ v2 ⇒ ⋯ ⇒ vn。
  2. 把 v 插进去。单向连通保证 v 和每个 vi 之间至少一个方向可达。
    • 若 v ⇒ v1:把 v 放最前面。
    • 若 vn ⇒ v:把 v 放最后面。
    • 否则 v1 ⇒ v 且 v ⇒ vn。从左往右找第一个满足 v ⇒ vi 的位置 i(i ≥ 2),那么 vi−1 ⇒ v,于是 ⋯ ⇒ vi−1 ⇒ v ⇒ vi ⇒ ⋯,v 插进了中间。

课件的图就是在演示这个"找插入位置"的过程(红色箭头表示 v 和各点的可达方向)。课件第 37–38 页还处理了一个细节:去掉 v 之后,剩下的图可能不再单向连通(原来的通路可能要经过 v),所以要先把剩下的点分成几段通路,再逐段扩充。

另一种更干净的证法(供参考)

在单向连通图里,"可达"关系有两个性质:任意两点至少一个方向可达,并且可达有传递性(u⇒v,v⇒w 推出 u⇒w)。这样的关系可以把所有点排成一列 v1, …, vn,使前面的总能到后面的(就像比较大小然后排序,每次挑一个"能到达其余所有点"的点放在最前)。然后把 v1⇒v2, v2⇒v3, … 这些通路首尾接起来,就是完备通路。∎

例 9(课件第 26 页的图)判断下图的连通性,若是强连通请写出一条完备回路。
展开解答

从 a 出发:a→b→e→c,e→d,能到所有点。再看其他点能否回到 a:b→a;e→d→a;c→b→a;d→a。每个点都能到 a,a 又能到每个点,所以任意两点都能经过 a 互达,强连通。

完备回路:a → b → e → c → b → a → d → a,经过了全部 5 个点(b、a 重复出现是允许的)。也可以是 a → b → e → c → b → e → d → a。

10.6

(续)竞赛图、分支、回路与非循环图

课件③ 第 41–67 页

这一部分在上一节"连通"的基础上继续往下走,回答四个问题:一张不连通的图能拆成几块(分支);什么样的图本身就是一个圈(回路、半回路、有向回路);怎么判断图里有没有圈(W-过程、非循环图);边要多到什么程度图才一定连通(连通的充分条件)。

竞赛图与勒代定理

定义 竞赛图(tournament,又称有向完全图)

有向图 G = ⟨V,E⟩,对任意两个不同的顶点 u、v,⟨u,v⟩ ∈ E 或 ⟨v,u⟩ ∈ E,并且恰好只有一个。

名字来自循环赛:每两个选手恰好比一场,u → v 表示 u 赢了 v。把 Kn 的每条边任意定一个方向,得到的就是竞赛图。

课件第 43 页的定义只写了"或者",没有写"恰好一个"。通常的定义要求两点之间只有一个方向(一场比赛只有一个胜者),下面的证明也用到了这一点。

勒代定理(Rédei, 1934)

每一个竞赛图都有一条有向哈密顿通路,即一条经过每个顶点恰好一次的有向通路(不要求回到起点)。

它和上一节定理 10.6.3 的关系:竞赛图里任意两点之间都有一条边,当然单向连通,所以由定理 10.6.3 它有完备通路;勒代定理更进一步,说这条通路可以做到每个点只经过一次。

证明(对点数归纳,就是"插队"):1 个点时显然成立。假设前 k 个点已经排成一条有向通路 v1 → v2 → ⋯ → vk,现在加入新点 v,要把它插进队伍里:

  1. 如果 v → v1:把 v 排在最前面,变成 v → v1 → ⋯ → vk。
  2. 否则一定是 v1 → v(竞赛图里两点之间恰好一条边)。此时如果 vk → v,把 v 排在最后面。
  3. 剩下的情况是 v1 → v 而 v → vk。从左往右找第一个满足 v → vi 的位置 i(因为 v → vk,一定找得到,而且 i ≥ 2)。i 是第一个,所以 v 没有指向 vi−1,只能是 vi−1 → v。于是 ⋯ → vi−1 → v → vi → ⋯,v 插在了中间。

每次插入后仍是一条经过所有已加入点、每点一次的有向通路,归纳完成。∎

例(课件第 44 页)象棋比赛中每两名选手之间都要赛一场。证明:可以给选手编号,使得每一名选手都没有输给编号紧接在他后面的那位选手。
展开解答

建图:选手是点,"u 没有输给 v"就画 u → v(u 赢 v 就从 u 指向 v;如果是和棋,两个方向都满足"没输",随便定一个方向)。每两人恰好一场,所以这是一个竞赛图。

由勒代定理,存在有向哈密顿通路 v1 → v2 → ⋯ → vn。按这个顺序编号 1, 2, …, n,每条边 vi → vi+1 正好说明第 i 号没有输给第 i+1 号。∎

插队实验

随机生成一场 5 人循环赛(箭头从胜者指向负者),按上面的证明逐个把选手插进队伍,最后的排列就是一条哈密顿通路(橙色)。

部分概念关系图(课件第 41 页)

这张表是这一节的"地图",后面每个概念都能在里面找到位置。每一行的"⟺"表示:图具有左边的连通性,当且仅当它恰好有一个对应的分支。

连通性⟺ 分支本身是一个"圈"的图
无向图连通恰有 1 个分支回路(连通 2 度正则图)
有向图强连通恰有 1 个强分支有向回路;基础图是回路的叫半回路
单向连通恰有 1 个单向分支
弱连通恰有 1 个弱分支

极大子图与分支

定义 极大子图

设 G′ 是 G 的具有某性质 P 的子图,并且对 G 的任意具有性质 P 的子图 G″,只要 G′ ⊆ G″ 就有 G′ = G″,则称 G′ 是 G 相对于性质 P 的极大子图。

说人话:"极大"和"最大"不是一回事

极大的意思是"已经不能再扩大了":在保持性质 P 的前提下,再往里加任何点或边都会破坏 P。最大的意思是"在所有满足 P 的子图里规模最大"。

打个比方:一个班的若干个小团体,每个小团体都"不能再拉人进来"(极大),但它们人数可以不一样,人数最多的那个才是"最大"。一张图可以有好几个极大子图,它们大小不同。这个区别在 10.8 节会反复出现。

定义 分支

无向图 G 的极大连通子图称为 G 的分支(连通分支),分支个数记为 W(G)。
有向图 G 的极大强连通子图称为强分支,极大单向连通子图称为单向分支,极大弱连通子图称为弱分支。

定理

(1) 连通无向图恰有一个分支,非连通无向图的分支多于一个。
(2) 强连通(单向连通、弱连通)有向图恰有一个强分支(单向分支、弱分支);否则多于一个。

道理很直接:G 本身连通时,G 就是一个连通子图,而且不能再扩大,所以它就是唯一的分支。

连通无向图:1 个分支
非连通:3 个分支 {1,2,5}、{4}、{3,6,7}
孤立点 4 自己也算一个分支

有向图的三种分支(课件第 47–48 页)

用上一节距离矩阵那张有向图来看:

4 个强分支:G[{v1,v2,v3}](橙色)、G[{v4}]、G[{v5}]、G[{v6}]
单向分支 ①:G[{v1,…,v5}]
单向分支 ②:G[{v5,v6}]

弱分支只有 1 个,就是整张图(忽略方向后连通)。

  • 为什么 {v1,v2,v3} 是强分支:沿着 v1→v2→v3→v1 绕圈,三点两两互达。加入 v4 就不行了,v4 回不到 v3。
  • 为什么 {v1,…,v5} 是单向分支:任意两点至少一个方向能到(比如 v1⇒v5,v2⇒v4)。加入 v6 就不行:v6 只能到 v5,v6 和 v1 互相都到不了。
  • 为什么 {v5,v6} 也是单向分支:v6⇒v5,而且它已经不能扩大:再加入任何一个点 x ∈ {v1,…,v4},x 和 v6 互相都到不了。
课件第 48 页的问题:每个结点(每条边)是否恰处于一个分支中?
结点边
强分支恰在一个("互达"是等价关系,强分支就是等价类)不一定。e4、e5、e6 不在任何强分支里,因为它们两端不能互达
单向分支至少在一个,可能在多个。v5 同时在两个单向分支里至少在一个(一条边的两个端点本身就单向连通),可能在多个
弱分支恰在一个恰在一个

强分支能把点"分干净",原因是"u、v 互达"满足自反、对称、传递,是一个等价关系。"单向可达"不满足传递性(v1⇒v5、v6⇒v5,但 v1 和 v6 互不可达),所以单向分支会重叠。

例(课件第 50–51 页)设 G = ⟨V,E⟩。证明:G 是连通图,当且仅当对 V 的每个划分 {V1, V2},都存在一条边,它的两个端点分别属于 V1 和 V2。
展开解答

"划分" {V1, V2} 指:两个都非空、不相交、并起来是 V。所以结论说的是:不管怎么把点分成两堆,总有一条边跨在两堆之间。

充分性(⇐,反证):假设 G 不连通,则 G 至少有两个分支。取其中一个分支 G1,令 V1 = G1 的点集,V2 = V − V1,这是一个划分。分支是"极大"连通子图,所以不可能有边从 V1 连到外面(否则把那条边和那个点加进来仍连通,与极大矛盾)。于是这个划分没有跨边,与条件矛盾。

必要性(⇒):任取 v1 ∈ V1,v2 ∈ V2。G 连通,所以有一条从 v1 到 v2 的路 v1 = u0, u1, …, uk = v2。起点在 V1,终点在 V2,所以沿路走的过程中一定有某一步从 V1 跨到 V2:取第一个落在 V2 的点 uj,则 uj−1 ∈ V1,边 (uj−1, uj) 就是要找的跨边。∎

课件用的是对路径长度归纳:看路上与 v1 相邻的点 v′,若 v′ ∈ V2,边 (v1, v′) 就是跨边;若 v′ ∈ V1,就从 v′ 出发、路径短了一步,由归纳假设得证。两种写法是同一个意思。

回路、半回路、有向回路(作为"图")

先分清两个"回路"

上一节定义 10.6.5 的"回路"是一条走法(一个点的序列,可以重复)。这里的"回路"是一种图:这张图本身长成一个圈。两者用的是同一个词,看上下文区分:"G 有一条回路"指走法,"G 是回路"指图。

定义
  1. 回路:连通的 2 度正则(无向)图。
  2. 半回路:基础图是回路的有向图(忽略方向是一个圈,箭头方向随便)。
  3. 有向回路:每个结点的出度和入度都为 1 的弱连通有向图(箭头顺着一个方向绕一圈)。
  4. 回路(半回路、有向回路)的长度是它的边数。
有向回路:顺着箭头能绕一圈
半回路:去掉方向是圈,
但顺着箭头绕不回来
也是半回路

为什么"连通"不能省:两个分开的三角形也是 2 度正则图,但它是两个圈,不是一个回路。为什么有向回路要求"弱连通":两个分开的有向三角形每点出入度都是 1,同样要排除。有向回路一定是半回路,反之不然。

定理(课件第 54–56 页)

设 v 是图 G 的任意结点。G 是回路(或有向回路),当且仅当

(i) G 的阶与边数相等(|V| = |E|),并且
(ii) G 中存在一条从 v 到 v 的回路,除了 v 在其中出现两次(起点和终点)外,其余每个结点和每条边都在该回路中恰好出现一次。

条件 (ii) 说的是:从 v 出发能"一笔画"地把所有点、所有边各走一遍回到 v。

充分性((i)(ii) ⇒ G 是回路):

  1. 由 (ii),所有点都在一条闭合走法上,任意两点都能沿着它互相到达,G 连通。
  2. 回路每经过一个点,就"进来一条边、出去一条边",所以每个点的度至少是 2。
  3. 如果某个点的度大于 2,那么 2|E| = ∑d(v) > 2|V|,与 (i) 的 |V| = |E| 矛盾。所以每点度恰好为 2,G 是连通 2 度正则图,即回路。

必要性(G 是回路 ⇒ (i)(ii)):

  1. (i):每点度为 2,由握手定理 2|E| = ∑d(v) = 2|V|,所以 |E| = |V|。
  2. (ii):从 v 出发沿一条边走。到达一个新点时,它有 2 条边,进来用掉一条,还剩一条可以出去,所以不会卡住。也不会第二次走到 v 以外的某个旧点(那需要它有第 3 条边)。点数有限,最终一定回到 v。这样走出的闭合路径上的点和边构成一个连通的 2 度正则子图,它不和其他点相连,而 G 连通,所以它就是 G 的全部。

有向回路的版本相同,把"度为 2"换成"出度、入度都是 1"。课件第 56 页用的是对阶数归纳:在 n+1 阶有向回路里删掉 v,把它前后两点 vn、v1 直接连上,得到 n 阶有向回路(可能出现重边),由归纳假设拿到通路后再把 v 插回去。

有回路与非循环图

定义

(1) 如果回路(有向回路、半回路)C 是 G 的子图,就称 G 有回路(有向回路、半回路)C。
(2) 没有回路的无向图,和没有半回路的有向图,称为非循环图。

注意有向图的"非循环"要求很严有向图要成为非循环图,必须连半回路都没有,也就是忽略方向后没有圈(基础图是森林)。只是"没有有向回路"还不够。下面 W-过程实验里的那张图就是例子:它没有有向回路,但不是非循环图。
定理(课件第 58 页)

如果有向图 G 有子图 G′,使得 G′ 中每个结点 v 都有 doG′(v) > 0(出度为正),则 G 有有向回路。把"出度"换成"入度",结论同样成立。

直觉:在 G′ 里每个点都有路可走(都能出去),从任何点出发一直走,永远不会卡住;但点只有有限个,迟早会走到走过的点,这就绕成了一个圈。

证明(入度版,课件写法):取 G′ 中最长的基本通路 v0 → v1 → ⋯ → vn。v0 的入度大于 0,所以有边 e = ⟨v, v0⟩。如果 v 不在这条通路上,把 v 接在最前面就得到更长的基本通路,与"最长"矛盾。所以 v 就是通路上的某个 vi,于是 v0 → ⋯ → vi → v0 是一条有向回路。∎

反过来读(逆否命题):没有有向回路的有向图,它的每个子图里都至少有一个出度为 0 的点(也至少有一个入度为 0 的点)。W-过程就是靠这一点工作的。

W-过程:判断有向图是否有有向回路

W-过程

设 v 是有向图 G 中 do(v) = 0 或 di(v) = 0 的结点。从 G 中去掉 v 及与之关联的边,得到 G − {v},这个操作叫一次 W-过程。

  • G 有有向回路 ⇔ G − {v} 有有向回路。
  • 若 n 阶有向图 G 没有有向回路,则经过 n−1 次 W-过程得到平凡图。

为什么删 v 不影响答案:有向回路上每个点出度、入度都至少为 1。v 的出度或入度为 0,它不可能在任何有向回路上,删掉它不会破坏任何回路,也不会凭空造出回路。

为什么无回路时一定能删到只剩 1 个点:由上面定理的逆否命题,没有有向回路的图里总有出度为 0 的点,所以每一步都有点可删;删完后的子图仍然没有有向回路,可以继续。反过来,如果中途卡住(剩下的每个点出度、入度都大于 0),由定理,图里一定有有向回路。

这就是数据结构课里的"拓扑排序":按删除顺序倒过来排,就得到一个使所有边都从前指向后的顶点顺序。课件说课程选修系统检测先修课是否循环依赖、编译器检测递归调用,用的都是这个方法。

W-过程实验

课件第 60 页的有向图。每次删除一个出度或入度为 0 的点(优先删出度为 0 的)。切换到"看作无向图"可以检查它是不是非循环图;勾选"加一条边 v7→v1"可以看有回路时是怎么卡住的。

判断一个图是否是非循环图(课件第 61 页)

定理

图 G 不是非循环图,当且仅当 G 有子图 G′,使得 G′ 中每个结点都有 dG′(v) > 1(度至少为 2)。
等价地:G 是非循环图,当且仅当 G 的每个子图 G′ 中都存在一个结点 v,使得 dG′(v) ≤ 1。

这里的度对有向图按基础图算(入度加出度)。理由和有向版本一样:在每个点度都 ≥ 2 的子图里,走到一个点总能从另一条边离开,走不到头,迟早绕成圈;反过来,一个圈本身就是每点度为 2 的子图。

判定算法:令 G0 = G。只要 Gi 里有度 ≤ 1 的结点 vi,就令 Gi+1 = Gi − {vi}。得到序列 G0, G1, …, Gm(m ≤ n−1)。如果 Gm 是平凡图,G 是非循环图;否则(卡住了)不是。直观上就是不断"剪掉叶子"。

课件第 61 页的图 (a) 就是 W-过程那张图,它标注"不是非循环图":忽略方向后 v1、v2、v5 构成三角形,这是一个半回路。在上面实验里切到"看作无向图",一个点都删不掉。

连通的充分条件(课件第 62–63 页)

例题(两个结论)

设 G 为 n 阶简单无向图。
(1) 若 G 中任意两个结点的度数之和 ≥ n−1,则 G 连通。
(2) 若 G 中每个结点都有 d(v) ≥ (n−1)/2,则 G 连通。

(1) 的证明:任取两个结点 u、v,证明它们之间有路。

  • 如果 u、v 相邻,已经连通。
  • 如果不相邻:简单图中,u 的邻居和 v 的邻居都只能在其余 n−2 个点里(不能是自己,也不能是对方)。可是 d(u) + d(v) ≥ n−1 > n−2,两个邻居集合的大小加起来超过了 n−2 个"位置",由抽屉原理它们必有公共元素 w。于是 u–w–v 是一条路。

所以任意两点都连通(而且距离不超过 2)。

(2) 的证明:对任意 u、v,d(u) + d(v) ≥ (n−1)/2 + (n−1)/2 = n−1,由 (1) 得 G 连通。

条件不能再弱两个不相连的 Kk 组成的图有 n = 2k 个点,每点度为 k−1 = (n−2)/2,任意两点度数和为 n−2,只比条件少 1,就已经不连通了。所以 n−1 这个界是紧的。

分支数与边数的关系(课件第 64–67 页)

例题

设 G 为 n 阶简单无向图,有 k 个分支、m 条边,则

m ≤ (n−k)(n−k+1) / 2

先猜边数最多的情形:k 个分支,要让边尽量多,就把点尽量"堆"到一个分支里,并且让它是完全图。也就是 k−1 个孤立点 + 一个 Kn−k+1,边数恰好是 (n−k+1)(n−k)/2。课件第 64 页的图是 n=7、k=4:K4 加 3 个孤立点,6 条边,(7−4)(7−4+1)/2 = 6。

n=7,k=4 时边最多:K4 + 3 个孤立点

证明:

  1. 先让每个分支变成完全图。在一个分支内部加边不会把两个分支连起来,分支数 k 不变,边数只增不减。所以只需证明"每个分支都是完全图"时结论成立。
  2. 设各分支点数为 n1, …, nk,n1 + ⋯ + nk = n,每个 ni ≥ 1。边数
    M = [n1(n1−1) + ⋯ + nk(nk−1)] / 2
  3. 令 T = max ni。其余 k−1 个分支每个至少 1 个点,所以 T ≤ n − (k−1) = n−k+1。
  4. 每一项 ni(ni−1) ≤ T(ni−1),所以
    M ≤ T[(n1−1) + ⋯ + (nk−1)] / 2 = T(n−k) / 2 ≤ (n−k+1)(n−k) / 2

∎ 课件第 65–66 页还给了另一种思路:比较两个各有 n1, n2 ≥ 2 个点的完全图分支(边数 B)和"一个 Kn1+n2−1 加一个孤立点"(边数 A),算出 A − B = (n1−1)(n2−1) > 0。意思是:把一个分支的点挪到另一个分支里,只留一个孤立点,边数会变多。反复这样做,最后就得到"k−1 个孤立点 + 一个大完全图"。

k = 1 时公式给出 n(n−1)/2,正是 Kn 的边数。反过来用:n 阶简单图如果边数 > (n−1)(n−2)/2(k=2 时的上界),它一定连通。

10.7

割集与圈

课件③ 第 69–86 页

上一节问"图连不连通",这一节问"图连得牢不牢":最少拿掉哪些点或边,图就断开了?这些关键的点和边就是网络里的薄弱环节。

引例:嗅探器(ZJOI 2004)

红军要在蓝军网络的某台中间服务器上装一个嗅探器,截获两个信息中心之间的所有数据包。数据包可以走不同的路。问:装在哪台服务器上,才能保证所有数据包都经过它?

信息中心 2 和 4(蓝色)
按原题样例的边表(没有 3–4)

换成图论的说法:找一个点 v(不是 2 也不是 4),使得从 2 到 4 的每条路都经过 v。上图中 4 只连着 1,任何到达 4 的路都必须先经过 1,所以答案是 1 号服务器。下面的割点定理会告诉我们,这样的 v 正是"割点"的另一种刻画。

课件第 71 页的图里还画了一条 3–4 的连线。如果真有这条边,2 到 4 就有 2–1–4 和 2–3–4 两条不共用中间点的路,装在哪台中间服务器上都截不全。原题样例的边表里没有 3–4,答案是 1。

点割集与割点

定义 点割集

设无向图 G = ⟨V,E⟩ 是连通图,点集 V1 ⊂ V 满足:

  • G 删除 V1 的所有结点后,得到的子图不连通;
  • 而删除 V1 的任意真子集后,得到的子图仍连通。

则称 V1 是 G 的一个点割集。若 {v} 是点割集,称 v 为割点。

W(G − V1) > W(G) 且 ∀V′ ⊂ V1,W(G − V′) = W(G)
两个条件各管什么

第一条说"删掉它够用":图断开了。第二条说"一个都不多余":少删任何一个点都断不开。所以点割集是一个"极小"的断开点集。"删除一个点"指连同它关联的所有边一起删掉。

形式化写法里的 W(·) 是分支数。G 连通时 W(G) = 1,"W(G − V1) > W(G)"就是"删完不连通"。

例 1(课件第 74 页):删去 s,W 从 1 变成 2,
s 是割点
例 2(课件第 75 页)在下图中,找出所有点割集和割点。
展开解答

先找割点(逐个删一个点看是否断开):

  • 删 v5:{v1,v2,v3,v4} 和 {v6,v7} 断开。v5 是割点。
  • 删 v6:v7 被孤立。v6 是割点。
  • 删其他任一点,剩下的仍连通。

再找两个点的点割集:删 v1 和 v4,v2 的两个邻居都没了,v2 被孤立。而单独删 v1 或单独删 v4 都不会断开,所以 {v1, v4} 是点割集。

还有没有别的?像 {v3, v5} 删掉后也不连通,但它的真子集 {v5} 已经能断开,违反"任意真子集删除后仍连通",所以不是点割集。我用程序枚举了所有点集,结果只有 {v1,v4}、{v5}、{v6},与课件一致。

v2、v3、v7 不在任何点割集中:比如 v7 是"叶子",删掉它只会少一个末端,别的点都还连着;把它加进任何点集里,都会让那个点集不再"极小"。

边割集与割边(桥)

定义 10.7.1 边割集

设 G 是连通无向图。课件的写法是:对任意 E′ ⊆ E″ ⊆ E,图 G′ = ⟨V,E′⟩ 和 G″ = ⟨V,E″⟩ 都是 G 的子图,若 (1) G′ 是不连通图,(2) 对于任意满足 E′ ⊂ E″ 的 E″,G″ 仍是连通图,则称边集 E \ E′ 为 G 的一个割集(边割集)。

若边割集 T = {e},称 e 为 G 的割边或桥(cut edge, bridge)。

把这个定义翻译一下

令 T = E \ E′,T 就是"要删掉的边",E′ 是"删完剩下的边"。

  • (1) "G′ 不连通":删掉 T 后图断开了(删得够)。
  • (2) "E″ 比 E′ 多任何边都连通":只要少删 T 中的任何一条(把它留下),图就还连通(一条都不多余)。

所以和点割集完全平行:边割集 = 删掉后图断开、而少删任意一条都不断开的边集。注意删边时点保留(G′ 的点集还是 V)。

课件第 77 页:橙色边是桥,删掉它图就断成两半
定理 10.7.1

对连通无向图 G,把 G 的结点划分成两个不相交的子集 V1、V2,使每个子集的导出子图都是连通的,则连接这两个子集的边的集合是 G 的一个割集。

为什么:设 T 是所有一端在 V1、另一端在 V2 的边。

  • 删掉 T:V1 和 V2 之间没有边了,图断开(够用)。
  • 少删 T 中任意一条边 e:e 把 V1 和 V2 接上,而 V1、V2 内部各自连通,所以整个图又连通了(不多余)。

"每个子集的导出子图连通"这个条件不能少。如果 V1 自己内部就是断开的两块,跨边集合里可能有多余的边:只删其中一部分图就已经断了。

例(课件第 78 页,图 10-11)指出下图的割点(集)和割边(集)。
展开解答

v3 是割点:删掉 v3,左边 {v1,v2} 和右边 {v4,v5} 断开。

{(v1,v3), (v2,v3)} 是边割集:用定理 10.7.1,取 V1 = {v1,v2}、V2 = {v3,v4,v5},两边的导出子图都连通,它们之间的边恰好就是这两条。同理 {(v3,v4),(v3,v5)}、{(v1,v2),(v1,v3)} 等也是边割集。

没有割边:每条边都在某个三角形上,删掉任意一条,绕三角形的另外两条边仍能走通。

这个例子说明:有割点不一定有割边。

圈与距离

定义 10.7.2–10.7.4

圈:一条闭合链 (u1, u2, …, un, u1) 中各结点 u1, …, un 均不同,并且所有边也不同。(就是上一节的"基本回路"。)
长度:链(或圈)所含的边数,链 P 的长度记为 |P|。
距离:无向图中 u、v 之间最短链的长度,记 d(u,v)。

无向图的距离满足四条性质:不连通时 d(u,v) = ∞;d(u,u) = 0;d(u,v) = d(v,u)(对称);d(u,w) ≤ d(u,v) + d(v,w)(三角不等式:先到 v 再到 w 也是一条从 u 到 w 的链,最短链不会比它长)。

课件这里用"链"指无向图中的通路,"路"一般指不重复点的链。

割点、割边的等价刻画

定理(割点)连通无向图 G 中的结点 v 是割点 ⇔ 存在结点 u 和 w(都不是 v),使得连接 u 和 w 的每条路都经过 v。

⇐:u 到 w 的每条路都经过 v,那么在 G − {v} 中 u 和 w 之间一条路都没有,G − {v} 不连通,v 是割点。

⇒:v 是割点,G − {v} 至少有两个分支 G1、G2。取 u ∈ G1、w ∈ G2。G 连通,所以 G 中有 u 到 w 的路。对其中任意一条路 Γ:如果 Γ 不经过 v,它就完整地留在 G − {v} 里,u、w 就在同一个分支中,矛盾。所以 Γ 必经过 v。∎

回到嗅探器:要找的就是这样一个 v,只不过 u、w 已经指定为两个信息中心。

定理(割边)连通无向图 G 中的边 e 是割边 ⇔ 存在结点 u 和 w,使得连接 u 和 w 的每条路都经过 e。

证明和割点完全一样,把"删点 v"换成"删边 e"。

定理(课件第 84 页)无向图 G 的边 e 是割边 ⇔ e 不包含在 G 的任何基本回路(圈)中。

证明:设 e = (x,y)。下面四句话一个推一个,每一步都是"当且仅当":

  1. e 是割边
  2. ⇔ 删掉 e 后,x 和 y 落在 G − {e} 的不同分支中(删掉 e 只可能把 e 的两端拆开,别的点之间原来怎么连还怎么连)
  3. ⇔ 在 G − {e} 中不存在 x 到 y 的路
  4. ⇔ e 不在任何基本回路中。因为:如果 e 在某个基本回路上,回路去掉 e 剩下的部分就是一条 x 到 y、不用 e 的路;反过来,如果有一条不用 e 的 x–y 基本路,把 e 接上就是一个包含 e 的基本回路。

∎ 一句话:桥就是不在任何圈上的边。在圈上的边删了可以绕道,桥删了没有路可绕。

Tarjan 算法:一次 DFS 找出所有割边

最直接的办法是逐条边删掉、做一次连通性检查:一共 |E| 条边,每次检查 O(|V|+|E|),总共 O(|E|(|V|+|E|))(课件写的是 O(|V|(|V|+|E|)),那是逐个点判断割点的代价)。1986 年图灵奖得主 Robert Tarjan 给出的算法只需要做一次深度优先搜索(DFS),复杂度 O(|V|+|E|)。

第一步:做一次 DFS,分出两种边

从任一点出发做 DFS。沿着它"第一次走到新点"所用的边(树枝边)构成一棵 DFS 树,其余的边叫返祖边(回边)。

关键事实在无向图的 DFS 中,每条非树边都连接一个点和它在 DFS 树上的祖先,不会连到"旁边那一支"。

理由:假设 DFS 正在处理 u,u 有一个邻居 w 还没被访问,DFS 一定会在离开 u 之前访问 w,所以 w 会成为 u 的后代。也就是说,相邻的两个点之间一定是祖先—后代关系。

这立刻告诉我们:返祖边一定不是桥(它和树上的那段路构成一个圈),只有树枝边才可能是桥。

第二步:给每个点记两个数

  • dfs[u]:u 被访问的次序(时间戳),第几个被访问就是几。
  • low[u]:从 u 的子树里的任意点出发,最多走一条返祖边,能到达的点的时间戳的最小值。直观地说,就是"u 这一支最高能爬回到哪"。

计算方法:先令 low[u] = dfs[u];遇到返祖边 (u, w) 时 low[u] = min(low[u], dfs[w]);子结点 v 处理完返回时 low[u] = min(low[u], low[v])。

第三步:判定

判定条件

(u, v) 是割边 ⇔ (u, v) 是树枝边(u 是 v 的父结点),并且 dfs[u] < low[v]。

为什么:low[v] > dfs[u] 意思是 v 的整棵子树,靠返祖边最高也只能爬到 v 自己这一层,碰不到 u 或 u 上面的点。那么子树和外界唯一的联系就是树枝边 (u, v),删掉它子树就掉下来了,所以是桥。反之,如果 low[v] ≤ dfs[u],子树里有一条返祖边能绕到 u 或更高的地方,(u, v) 删了也能绕过去,就不是桥。

Tarjan 逐步演示(课件第 86 页的图)

每点一下执行一步。点上方的数字是 dfs/low。橙色实线是树枝边,蓝色虚线是返祖边,红色粗线是找到的桥。DFS 时邻居按编号从小到大访问,得到的 DFS 树和课件完全一致。

最后的结果与课件第 86 页的表一致:dfs = (1,2,3,4,5,6,7,9,8),low = (1,1,1,1,2,6,7,1,1)(按结点 1~9 排列)。检查每条树枝边:

  • (5, 6):dfs[5] = 5 < low[6] = 6,是桥。
  • (6, 7):dfs[6] = 6 < low[7] = 7,是桥。
  • (4, 5):low[5] = 2(5 有返祖边连到 2),dfs[4] = 4 ≮ 2,不是桥。
  • (4, 9):low[9] = 1(经 8 的返祖边到 1),不是桥。其余同理。

同样的 dfs/low 也能找割点:非根结点 u 是割点 ⇔ 它有某个子结点 v 满足 dfs[u] ≤ low[v](注意是 ≤);根结点是割点 ⇔ 它在 DFS 树上有至少两个子结点。这张图里割点是 5 和 6。

10.8

支配集、覆盖集与独立集

课件③ 第 88–100 页

这一节的概念都是同一个模式:从图里选一些点或边,要求它们满足某种"照顾到"或"互不冲突"的条件,然后问最少(或最多)要选几个。下面先给全景,再逐个讲。

先看清选的是点还是边
名称选什么条件求
支配集(10.8.1)点没选中的每个点,都和某个选中的点相邻最少
覆盖集(10.8.4,课件用法)边每个点都是某条选中边的端点("边覆盖点")最少
独立集(10.8.7,课件用法)边选中的边两两不相邻(不共用端点),即匹配最多
点覆盖(第 99–100 页)点每条边至少有一个端点被选中("点覆盖边")最少

本课件的"覆盖集"和"独立集"是边的集合。很多教材里"独立集"指两两不相邻的点集,"覆盖"指点覆盖。课件最后讲的"最小覆盖集问题"又换成了点覆盖。做题时先看清题目定义的是点还是边。

贯穿整节的"极小 / 最小"和"极大 / 最大"

极小:满足条件,并且去掉任何一个元素就不满足了(不能再减)。
最小:在所有满足条件的集合里,元素个数最少。

最小的一定是极小的(如果还能去掉一个,它就不是最少),但极小的不一定是最小的。极大 / 最大同理(不能再加 / 个数最多)。

下面所有例子都用课件里这张 8 个点、11 条边的图(v7、v8 分别在两条对角线的中间):

课件第 93–100 页的图

支配集

引例(选址问题,课件第 93 页):要在 n 个地点中选若干处设应急中心,使每个地点要么本身是应急中心,要么和至少一个应急中心直接相邻。为了省钱,中心要尽量少。应设几个?设在哪?

定义 10.8.1 支配集

设无向图 G = ⟨V,E⟩,V* ⊆ V。若对任意 u ∈ V − V*,V* 中都有 v 使得 (u,v) ∈ E,则称 v 支配 u,并称 V* 是支配集。

定义 10.8.2 · 10.8.3

极小支配集:V* 是支配集,并且它的任意真子集都不是支配集。
最小支配集:点数最少的支配集,即 min{|V*|}。

对照课件的图:

  • {v2, v3, v4, v6} 是支配集(课件第 95 页):v1 被 v2 支配,v5 被 v4 或 v6 支配,v7 被 v2 支配,v8 被 v3 支配。但它不是极小的:去掉 v4,v4 自己被 v3 支配,其余点照旧被支配,剩下的 {v2, v3, v6} 仍是支配集。
  • {v2, v5} 是最小支配集(课件第 96 页右图):v2 支配 v1、v3、v7,v5 支配 v4、v6、v8。
  • 为什么不可能只用 1 个点:度最大的点 v2、v5 度都是 4,一个点最多照顾到自己和 4 个邻居共 5 个点,不够 8 个。所以最小支配集大小是 2。程序枚举可知只有 {v2, v5} 和 {v3, v6} 两个。
  • {v1, v2, v3} 是极小支配集但不是最小的:去掉 v1,v6 就没人支配;去掉 v2,v7 没人支配;去掉 v3,v4 没人支配。它不能再减,可是比 {v2, v5} 多一个点。

所以选址问题的答案是:至少设 2 个应急中心,可以设在 v2、v5,或 v3、v6。

定理 10.8.4

设无向图 G 中无孤立结点,V1* 为 G 的一个极小支配集,则 G 存在另一个极小支配集 V2*,使得 V1* ∩ V2* = ∅。

课件只给了结论。证明分两步,核心是证明"剩下的点 V − V1* 本身也是支配集"。记 D = V1*。

  1. D 中每个点 v 都有邻居在 D 外面。 D 是极小的,去掉 v 后 D − {v} 不再是支配集,所以有某个点 w 没被 D − {v} 支配。分两种情况:
    • w 就是 v 自己:说明 v 在 D 里没有邻居。可是 G 没有孤立点,v 总有邻居,那这个邻居只能在 D 外面。
    • w 是 D 外面的点:w 原来被 D 支配,去掉 v 后就不被支配了,说明 w 唯一的 D 中邻居是 v。于是 w 就是 v 在 D 外面的邻居。
  2. 所以 V − D 是支配集:不在 V − D 中的点就是 D 中的点,由第 1 步它们都和 V − D 中的某点相邻。
  3. V − D 是支配集,但不一定极小。从中不断去掉多余的点,直到不能再去,得到一个极小支配集 V2* ⊆ V − D,它和 D 不相交。∎

例:{v2, v5} 是极小支配集,V − {v2,v5} = {v1,v3,v4,v6,v7,v8} 是支配集,从中可以减出 {v3, v6}。"无孤立点"不能去掉:孤立点必须属于每一个支配集(没人能支配它),两个支配集就不可能不相交。

覆盖集(课件定义:边覆盖点)

定义 10.8.4–10.8.6

设无向图 G = ⟨V,E⟩,E* ⊆ E。若对任意 u ∈ V 都有 e ∈ E* 使得 u | e(u 是 e 的端点),则称 e 覆盖 u,E* 是覆盖集。
E* 的任何真子集都不是覆盖集,则 E* 是极小覆盖集。
边数最少的覆盖集是最小覆盖集,即 min{|E*|}。

说人话:挑一些边,让每个点都至少被一条挑中的边碰到。显然有孤立点的图不存在覆盖集。

5 条边:极小覆盖集,但不是最小
(课件第 100 页左图)
4 条边:最小覆盖集
(课件第 100 页右图)

左图为什么是极小的:每条边都"独占"某个点,例如 (v1,v2) 是唯一碰到 v1 的边,(v2,v3) 是唯一碰到 v3 的边,去掉任何一条都有点没被覆盖。右图为什么是最小:一条边最多覆盖 2 个点,8 个点至少要 4 条边,右图正好 4 条,而且这 4 条边两两不共用端点。

独立集(课件定义:两两不相邻的边,即匹配)

定义 10.8.7–10.8.9

设无向图 G = ⟨V,E⟩,E* ⊆ E。若 E* 中任意两条边都不相邻,则称 E* 是独立集。
若对任意满足 E1* ⊂ E2* 的 E2*,E2* 都不是独立集,则 E1* 是极大独立集(再加任何一条边都会冲突)。
边数最多的独立集是最大独立集,即 max{|E*|}。

两条边"相邻"就是共用一个端点(10.2 节的定义)。所以独立集就是一组互不共用端点的边,在别的教材和算法课里叫匹配(matching):可以想成给点两两配对,每个点最多配一次。

独立集,但不是极大的
(课件第 102 页、第 103 页左图)
最大独立集:4 条边
(课件第 103 页右图)

课件第 103 页把左图放在"极大独立集"的定义旁边,但它只有 (v1,v2)、(v4,v5) 两条边,还可以再加入 (v6,v7) 和 (v3,v8) 而不冲突,所以严格按定义它不是极大的。加满之后就是右图。

覆盖集和独立集之间的联系(拓展)

上面两张"最小覆盖集"和"最大独立集"的右图用的是同一组 4 条边,这不是巧合。对没有孤立点的 n 阶图,有 Gallai 定理:最小覆盖集的边数 + 最大独立集的边数 = n。这里 4 + 4 = 8。

直观理解:先拿一个最大匹配(k 条边,覆盖 2k 个点),剩下 n − 2k 个点每个再补一条边,总共 k + (n−2k) = n − k 条边就覆盖了所有点。

最小点覆盖问题

定义(课件第 100 页)给定图 G = ⟨V,E⟩,求点集 A ⊆ V,使得对每条边 (u,v) ∈ E,u ∈ A 或 v ∈ A,并且 |A| 最小。

这里选的是点,要求每条边都被碰到,和上面的"覆盖集"方向正好相反。应用:软件测试里,"点覆盖"指测试用例要经过程序控制流图的所有结点,"边覆盖"指要经过所有边(课件第 99 页)。这个问题是 NP 难的,没有已知的多项式时间精确算法。

2-近似算法

  1. 令 E′ = ∅,A = ∅。
  2. 只要还有边没处理:任取一条边 (u, v),放进 E′,把 u 和 v 都加入 A,然后删掉所有和 u 或 v 相邻的边(它们已经被覆盖了)。
  3. 没边了就停止,输出 A。

A 是点覆盖:每条边要么被选进了 E′(两端都在 A 中),要么是因为和某条选中的边相邻而被删掉(共用的那个端点在 A 中)。

近似比 ≤ 2(为什么最多只比最优多一倍):

  • E′ 中的边两两不相邻(选一条就删掉它所有相邻边),也就是说 E′ 是一个独立集(匹配)。
  • 设 OPT 是最优解。OPT 要覆盖 E′ 的每条边,每条边至少要用一个端点。E′ 的边互不共用端点,所以 OPT 至少要用 |E′| 个不同的点:|E′| ≤ |OPT|。
  • A 恰好由 E′ 的端点组成:|A| = 2|E′| ≤ 2|OPT|,即 |A| / |OPT| ≤ 2。

在下面实验的"点覆盖"模式里可以运行这个算法,看看它在课件这张图上给出几个点。

POJ 3041 Asteroids:二部图上的点覆盖

题目:N×N 网格里有 K 颗小行星,第 i 颗在 (Ri, Ci)。一发光束能清除一整行或一整列。最少几发?课件的例子:小行星在 (1,1)、(1,3)、(2,2)、(3,2)。

建模:上面一排点代表"行",下面一排点代表"列",每颗小行星 (r, c) 连一条边 r–c。打一发行光束 = 选中一个行点,它清除这一行所有小行星 = 覆盖这个点关联的所有边。所以"清除所有小行星的最少发数" = 这个二部图的最小点覆盖。

选"行 1"和"列 2"(橙色)就覆盖了全部 4 条边:答案 2 发

一般图的点覆盖是 NP 难的,但二部图有 König 定理:最小点覆盖的点数 = 最大匹配的边数,而最大匹配可以用匈牙利算法在多项式时间内求出。这里最大匹配是 {行1–列1, 行2–列2},2 条,所以答案是 2。下界的理由和近似算法一样:匹配中的边互不共用端点,每条都需要一个不同的点去覆盖。

支配集 / 覆盖 / 独立集实验

先选模式,然后点击顶点(支配集、点覆盖)或边(覆盖集、独立集)进行选择。右边实时判断是否满足条件、是否极小(极大)、和最优值差多少。

11.2

第十一章 · 欧拉图

课件④ 第 1–32 页

第十一章叫"图的基本问题",本章内容分三块:穿程问题(欧拉图、哈密顿图、骑士周游)、通路问题(最短通路、关键通路)、匹配问题(二分图)。这份课件讲的是前两个:欧拉图和哈密顿图。

穿程问题(课件第 6 页)

对图 G,从一个指定结点出发,恰好经过每条边一次并回到该点,怎么走?(欧拉问题)
从一个指定结点出发,恰好经过每个结点一次并回到该点,怎么走?(哈密顿问题)
这类"遍历每条边"或"遍历每个结点"的问题统称穿程问题。

先记住这一节最重要的对比
欧拉(Euler)哈密顿(Hamilton)
要求每条边恰好一次,点可以重复每个点恰好一次,边不必全走
判断看度数的奇偶,简单的充要条件没有简单的充要条件,只有充分条件和必要条件
复杂度多项式时间,O(|V|+|E|) 就能判断NP 完全,一般只能搜索

哥尼斯堡七桥问题与一笔画

普雷格尔河把城市分成 4 块陆地:两岸 C、D 和两个岛 A、B,之间有 7 座桥。问:能否从某块陆地出发,每座桥恰好走一次,最后回到出发点?

陆地是点,桥是边(A–C、A–D 各有两座桥,是平行边)
度数:A = 5,B = 3,C = 3,D = 3

课件第 7 页把边写成三元组 (A, C, 1), (A, C, 2),第三个分量是给两座平行的桥编号,这样它们就是两条不同的边。

欧拉在 1736 年证明了这是不可能的,而且不能走成"不回到起点"的版本(课件第 8 页:"既无欧拉回路,又无欧拉路径")。理由在下面的定理里:4 个点的度都是奇数。

一笔画(课件第 9 页)

一张连通图能由一笔画出来(每条线恰好画一次、笔不离纸),当且仅当:

  • 每个交点处的线条数都是偶数(这时能画成回到起点的欧拉回路);或
  • 恰有两个交点处的线条数是奇数(这时能画成欧拉链,从一个奇点画到另一个奇点)。

"交点处的线条数"就是这个点的度。所以一笔画问题完全由度数的奇偶决定,下面是严格的定义和定理。

定义

定义 11.2.1 欧拉圈、欧拉图

设 G = ⟨V,E⟩ 是连通无向图,经过 G 中每条边一次且仅一次的简单回路称为欧拉圈,也称欧拉回路。具有欧拉圈的图称为欧拉图。

定义 11.2.2 欧拉链

经过 G 中每条边一次且仅一次的简单通路称为欧拉链(欧拉通路),起点和终点可以不同。

∀ek(ek ∈ E → ek ∈ ⟨e1, …, en, e1⟩)  ∀ei∀ej(ei, ej 在 ⟨e1, …, en, e1⟩ 的不同位置 → ei ≠ ej)

课件里那两行逻辑式正好对应"恰好一次"的两半:第一行说每条边都出现(至少一次),第二行说出现的边互不相同(至多一次)。

名称对照"欧拉圈 = 欧拉回路","欧拉链 = 欧拉通路 = 欧拉路径"。这里的"圈"只是名字,欧拉圈允许经过同一个点多次(课件第 13 页:"相同节点可能通过多次"),它不是 10.7 节那种"点也不重复"的圈。"简单回路"的意思是边不重复(10.6 节的定义)。

例:判断四个图(课件第 11–14 页)

G1:度数全为 2
欧拉圈 abcda
G2:e 度为 4,其余为 2
欧拉圈 abecdea
G3:只有 a、b 是奇点(橙色)
欧拉链 abcdaceb,无欧拉圈
G4:a、b、c、d 都是奇点
既无欧拉圈也无欧拉链

观察出的规律:有欧拉圈的图所有结点度数都是偶数;只有欧拉链的图恰有两个奇点,欧拉链就从一个奇点走到另一个;奇点有 4 个的 G4 两样都没有。下面把这个规律证明出来。

欧拉图的判定定理

定理(三个命题等价,课件第 15 页)

设 G 是连通无向图,下面三个命题等价:

  1. G 是欧拉图;
  2. G 中所有结点的度数都是偶数;
  3. G 是若干个边不重的圈的并(定理 11.2.3)。

证明分三步:先证 1 ⇒ 2(定理 11.2.2,必要性),再证 2 ⇒ 1(定理 11.2.1,充分性),最后 2 ⇔ 3 在证明 2 ⇒ 1 的过程中顺带得到。

必要性:欧拉图 ⇒ 连通且每点度为偶数(定理 11.2.2)

定理 11.2.2设图 G 是欧拉图,则 G 是连通图,并且 G 的每一个结点都是偶结点。

连通:欧拉圈经过所有边,任意两个有边的点都在这条回路上,沿回路就能互相到达。(定义里本来就要求了 G 连通。)

度为偶数:沿欧拉圈走一圈。每次"路过"一个点,都是从一条边进来、从另一条边出去,给这个点的度贡献 2。起点也一样:出发时用掉一条边,最后回来时又用掉一条,合起来也是 2。每条边恰好被走一次,所以每个点的度 = 2 × 它被路过的次数,是偶数。

充分性:连通且每点度为偶数 ⇒ 欧拉图(定理 11.2.1)

定理 11.2.1如果 G = ⟨V,E⟩ 是连通图,每个结点的度数是偶数,则 G 是欧拉图。

证明要用到一个辅助事实:每点度数都是偶数(且有边)的图里一定有圈。理由就是 10.6 节非循环图那条定理:所有点度 ≥ 2 的图不是非循环图。直观地说:从任一点出发沿没走过的边走,每进入一个点,因为度是偶数,进来用掉一条边后还剩奇数条,至少有一条可以出去,所以不会被卡住,点数有限,最后一定走回走过的点,形成一个圈。课件定义 11.2.3 的"极大路径"(不能再延长的路径)就是用来严格写这个论证的:极大路径的端点的所有邻居都在路径上,而它度 ≥ 2,所以它还连着路径上另一个点,这就构成圈。

证明(对边数 m 归纳,课件第 16–18 页):

  1. 起步:G 是平凡图(没有边)时结论成立。m = 1 时,连通且度为偶数,唯一的边只能是一个自环,自环本身就是欧拉圈。
  2. 归纳假设:设边数 ≤ k 时结论都成立,看 m = k+1。
  3. 取一个圈 C:由上面的辅助事实,G 中有圈 C。把 C 上所有的边删掉,得到生成子图 G′。
  4. G′ 的每个分支都满足归纳假设:C 经过每个点时用掉这个点的 2 条边(或 0 条),所以删掉 C 后每个点的度仍是偶数。G′ 可能不连通,设它有若干个分支 G′1, …, G′n,每个分支连通、度数全偶、边数 ≤ k,由归纳假设,每个 G′i 都是欧拉图,有自己的欧拉回路。
  5. 每个分支都和 C 有公共结点:G 是连通的,G′i 原来和外面相连只能靠 C 的边,所以 G′i 一定碰到 C,设公共结点为 vij。
  6. 拼接:沿着 C 走,每走到一个 vij,就先把 G′i 的欧拉回路从 vij 出发走一遍再回到 vij,然后继续沿 C 往前走。走回起点时,C 的边和所有 G′i 的边都恰好走了一次,这就是 G 的欧拉回路。∎

从这个证明还能看出:不断"拿出一个圈",最后边全部拿完,所以欧拉图是若干个边不相交的圈的并(命题 3)。反过来,若干个边不重的圈并起来,每个圈给经过的点贡献 2 度,所以每点度为偶数,连通时就是欧拉图。

例:把证明过程走一遍(课件第 19 页)

① 每点度数为偶,取圈 C = u4u3u5u4(橙色)
② 删去 C 后的分支 1
欧拉回路 u4u7u5u6u4
③ 分支 2
欧拉回路 u3u1u2u3

拼接:沿 C 从 u4 出发。在 u4 先插入分支 1 的回路 u4u7u5u6u4,然后沿 C 走到 u3,在 u3 插入分支 2 的回路 u3u1u2u3,再沿 C 经 u5 回到 u4:

u4u7u5u6u4u3u1u2u3u5u4

10 条边全部恰好走一次。注意 u4、u5、u3 都经过了两次,这在欧拉回路里是允许的。

欧拉链的判定(定理 11.2.4)

定理 11.2.4

无向图 G 中有连接 ui 和 uj(ui ≠ uj)的欧拉链,当且仅当 G 是连通图,并且 G 中只有 ui 和 uj 是奇结点。

证明思路:加一条边,把欧拉链变成欧拉回路(课件第 23–26 页)。令 e 是一条连接 v1、v2 的新边(如果 G 里已经有边 (v1,v2),就加一条与它平行的新边),G′ = G + {e}。下面每一步都是"当且仅当":

  1. G 有一条从 v1 到 v2 的欧拉链
  2. ⇔ G′ 有一条欧拉回路(欧拉链走到 v2 后再沿 e 回到 v1,就是 G′ 的欧拉回路;反过来,G′ 的欧拉回路去掉 e 就是 G 中 v1 到 v2 的欧拉链)
  3. ⇔ G′ 是欧拉图
  4. ⇔ G′ 中每个结点都是偶结点(上面的判定定理)
  5. ⇔ G 中恰有两个奇结点 v1 和 v2(加边 e 只让 v1、v2 的度各加 1,别的点不变)。∎

课件第 25–26 页讨论了 e ∈ E 的情形(v1、v2 本来就相邻),把 G − {e} 拆成两个圈来处理。用"加一条平行边"的写法可以把两种情形统一起来,因为欧拉图的判定定理对有平行边的图同样成立(七桥图本身就有平行边)。

判定口诀:数奇点

先确认图连通(孤立点不影响,忽略它),再数奇数度的点有几个:

  • 0 个:有欧拉回路,从任何点出发都行;
  • 2 个:没有欧拉回路,但有欧拉链,必须从一个奇点出发、到另一个奇点结束;
  • 4 个、6 个……:两样都没有。(奇点个数一定是偶数,这是握手定理的推论,所以不会出现 1 个或 3 个。)

序列图是欧拉图(课件第 21 页)

10.3 节的 0-1 序列图 Sm(m = 3 时 8 个点)每个点入度 2、出度 2,课件的 degreeset 函数算出度数全是 4,所以按无向图看它是欧拉图(自环 (0,0)、(7,7) 算 2 度)。对有向图也有同样的定理:弱连通有向图有有向欧拉回路 ⇔ 每个点入度 = 出度(课件第 21 页那两个公式就是入度、出度的定义)。

拓展:Sm 的有向欧拉回路有一个漂亮的用途。每条边对应一个 m+1 位 0-1 串,沿欧拉回路依次写下每条边的最后一位,就得到一个长 2m+1 的环形 0-1 序列,每个 m+1 位串恰好在其中出现一次(De Bruijn 序列)。这正是"序列图"这个名字的来源。

Fleury 算法:实际把欧拉回路找出来

判定定理只告诉我们"有没有",Fleury 算法告诉我们"怎么走"。

Fleury 算法(课件第 27 页)

输入:无向图 G。输出:从 v 到 w 的欧拉链或欧拉圈。

  1. 从任意一点开始(有两个奇点时必须从奇点开始),沿着没走过的边向前走;
  2. 在每个顶点,优先选择剩下的非桥边,除非只剩唯一一条边可走;
  3. 直到得到欧拉回路,或宣布失败。

"桥"是相对于剩下还没走的边而言的:把已经走过的边擦掉,在剩下的图里,如果某条边一删掉就会把图分成两块,它就是桥。

为什么不能随便走桥:桥是两块之间唯一的通道。如果另一侧还有没走的边,过了桥就回不来,留在这一侧的边就再也走不到了。所以只有在"别无选择"时才过桥,这时过桥后另一侧就是剩下的全部。

课件第 28 页的动画演示的就是在下面这张图上用 Fleury 算法从左上角出发走一圈。在下面的实验里可以一步步看到每一步为什么这样选,也可以自己点边走,故意走桥看看会怎么卡住。

欧拉回路 / Fleury 实验

选一张图,先看度数判断,再走。"Fleury 走一步"会按算法自动选边并说明理由;你也可以直接点击与当前点(橙色)相连的边自己走。走过的边标了序号。

例题(课件第 30 页)甲、乙两只蚂蚁分别在下图的 A、B 两点。甲提出:"咱俩比赛,看谁先把这个图中的九条边都爬遍后到达 E 点。"乙同意。两只蚂蚁速度相同、同时出发。问哪只蚂蚁先到达 E?
展开解答

先算度数:A = 4,B = 3,C = 4,D = 4,E = 3(B 和 E 之间没有边)。只有 B、E 是奇点。

由定理 11.2.4,图中有从 B 到 E 的欧拉链,例如 B → A → C → B → D → A → E → C → D → E(9 条边各一次)。乙从 B 出发沿这条链走,恰好爬 9 条边就到 E。

甲从 A 出发。A 是偶点,以 A 为起点、每条边恰好一次的走法要么是欧拉回路(终点回到 A),要么是欧拉链(但欧拉链的起点必须是奇点)。所以甲不可能只爬 9 条边就"爬遍且停在 E",至少要重复爬某条边,路程比 9 条边长。

答:乙先到达 E。(可以在上面的实验里选"蚂蚁例题",分别从 A 和 B 出发试试。)

中国邮递员问题

1962 年,中国数学家管梅谷提出并解决了这个问题,所以国际上叫它 Chinese Postman Problem。

问题(课件第 31 页)邮递员派信的街道是一个边赋权的连通图(权 = 街道长度)。从邮局出发,每条街道至少走一次,再回到邮局。怎样走总路程最短?

和欧拉问题的区别:欧拉要求每条边恰好一次,这里允许重复,只求总长最短。

  • 街道图本身是欧拉图:直接用 Fleury 算法走一条欧拉回路,每条街恰好一次,这显然最短。
  • 不是欧拉图:必须重复走一些街道。重复走一条边,相当于在图里给它再添一条平行边。目标变成:添一些边,使所有点的度都变成偶数(图变成欧拉图),并且添的边总权值最小。
管梅谷的结论(课件第 32 页)

若 W 是包含图 G 的每条边至少一次的回路,则 W 的总权值最小,当且仅当:

  1. G 的每条边在 W 中最多重复一次;
  2. 对于 G 的每个圈,圈上在 W 中重复的边的总权值不超过该圈上不重复的边的总权值(即不超过圈长的一半)。

两个条件为什么合理:

  • (1) 如果某条边重复了 2 次以上(一共走了 3 次或更多),去掉其中两次,每个端点的度都减 2,奇偶不变,仍然能走成回路,路程却更短。所以最优解里每条边最多多走一次。
  • (2) 在某个圈上,如果重复边的总长超过了圈长的一半,就把这个圈上"重复"和"不重复"对调:原来重复的改成不重复,原来不重复的改成重复。圈上每个点的度变化 0 或 ±2,奇偶不变,仍可走成回路,而重复的总长变成了原来不重复的那部分,更短。所以最优解一定满足 (2)。

课件最后提到 Edmonds–Johnson 算法可以在 O(n3) 时间内求出最优解。它的核心是:把所有奇点两两配对,每一对之间沿最短路添一遍重复边,选总长最小的配对方式。

例(用课件第 3、31 页的街区图)邮递员从邮局出发,要走遍下图每条街道再回到邮局,最短要走多少米?(图中右下角那栋建筑课件没写名字,记为 X。)
展开解答

第 1 步:数奇点。邮局(连老年公寓、区政府、学校)度 3,老年公寓度 1,区政府(邮局、卫生院、X)度 3,X(区政府、卫生院、学校)度 3,卫生院、学校度 2。奇点有 4 个:邮局、老年公寓、区政府、X。不是欧拉图,必须重复走一些街道。

第 2 步:奇点两两配对,比较三种配法。4 个奇点配成 2 对,只有 3 种配法。每对之间按最短路添重复边:

配对两对的最短路重复总长
{邮局, 老年公寓} + {区政府, X}1000 + 8001800
{邮局, 区政府} + {老年公寓, X}900 + (1000 + 1700)3600
{邮局, X} + {老年公寓, 区政府}1700 + (1000 + 900)3600

(邮局到 X 的最短路是 邮局–区政府–X = 1700,比 邮局–学校–X = 1800 短。)

第 3 步:最优是重复走"邮局–老年公寓"和"区政府–X"两条街。所有街道总长 1000+900+600+850+800+1000+1200 = 6350 米,加上重复的 1800 米,最短路程 8150 米。

添边后每个点度数都是偶数,可以走出一条回路,例如:邮局 → 老年公寓 → 邮局 → 区政府 → X → 区政府 → 卫生院 → X → 学校 → 邮局。

检查管梅谷的两个条件:每条边最多重复一次 ✓;圈 邮局–区政府–X–学校–邮局 长 3500,其中重复边 区政府–X 长 800 ≤ 1750 ✓;圈 区政府–卫生院–X–区政府 长 2650,重复 800 ≤ 1325 ✓;其余的圈同理。老年公寓那条街是桥,不在任何圈上,必须走两次(去和回)。

11.2

第十一章 · 哈密顿图

课件④ 第 33–60 页

哈密顿问题是爱尔兰数学家哈密顿在 1857 年发明的智力题("周游世界"游戏):正十二面体的 20 个顶点代表 20 个城市,从一个城市出发,每个城市恰好经过一次,最后回到出发城市。也就是判断图中是否存在一条遍历所有结点的简单回路。

定义 11.2.4 · 11.2.5

哈密顿通路:无向图 G 中穿过每个结点一次且仅一次的非闭合通路(也叫哈密顿链、哈密顿路)。
哈密顿圈:穿过每个结点一次且仅一次的圈(也叫哈密顿回路)。具有哈密顿圈的图称为哈密顿图。

和欧拉图的区别

哈密顿要求的是每个点恰好一次(起点终点重合的那一次除外),对边没有要求:不需要走遍所有边。欧拉要求每条边恰好一次,点可以重复。

两者互不蕴含。例如彼德森图(下面会看到)不是哈密顿图,也不是欧拉图(每点度为 3,奇数);领结图(两个三角形共用一点)是欧拉图,但不是哈密顿图(中间那个点必须经过两次);K4 是哈密顿图,但每点度 3,不是欧拉图。

正十二面体压平后的图(课件第 36 页)
20 个点,30 条边,每点度 3

为什么难(课件第 35–36 页):通常没有简单的判断方法。最直接的做法是把 20 个城市排成一个顺序,检查相邻两个是否有边。排列一共 20! = 2432902008176640000 种,即使每秒验证 10000 种,也要约 771 万年,复杂度 O(n!)。哈密顿圈问题是 NP 完全问题,至今没有已知的多项式时间算法。

回溯搜索:课件的周游算法

比起盲目枚举所有排列,更聪明的做法是沿着边一步步延长路径,走不下去就退回一步换个方向(回溯)。走不通的分支会被提前剪掉,不用把整个排列写完再检查。

第一步:建邻接表(课件第 39–40 页)

对每个结点 u,列出和它相邻的所有结点,记为 [u, [v | (u,v) ∈ E]]。课件的 adjacentlist(V,E) 对每个点 w 扫一遍边集,把另一端加进列表并排序。例如十二面体图中:

['a', ['b', 'n', 't']]   ['b', ['a', 'c', 'l']]   ['c', ['b', 'd', 's']]   ...

有了邻接表,"从 w 能走到哪些点"就能直接查到,不用每次扫全部边。

第二步:三个函数(课件第 41–46 页)

函数做什么
tourpath0(前进)取路径末尾结点 w,按邻接表顺序找第一个不在路径上的邻居 u,加到路径末尾;重复,直到路径长度达到 m(= 点数)或者末尾结点没有新邻居可走
tourpath1(回溯)弹出末尾结点 v,回到它前一个结点 u,在 u 的邻接表里从 v 之后继续找下一个不在路径上的邻居;找到就加上并结束,找不到就继续往回弹
tourpath若已经是一条完整的哈密顿通路(长度 = m),先回溯一步以便找下一条;否则交替执行前进和回溯,直到得到新的哈密顿通路或路径被弹空
Hamiltonpath(V,E,v0)建邻接表,从起点 v0 出发反复调用 tourpath,把找到的每一条哈密顿通路存进集合 paths

"从 v 之后继续找"是关键:回溯回到 u 时,排在 v 前面的邻居已经试过了,不用再试,这保证了不重复、不遗漏。

运行结果(课件第 47–51 页)

  • 十二面体图从 a 出发,共找到 162 条哈密顿通路。其中终点是 a 的邻居(b、n、t)的,再加一条边就能回到 a,构成哈密顿圈。课件第 47 页的代码 if path[-1] in ['b','n','t'] 就是在筛选这些,我用程序验证共有 60 条。所以十二面体图是哈密顿图,"周游世界"有解。
  • 彼德森图从每个结点出发都有 24 条哈密顿通路,10 个点共 240 条,但没有一条能闭合:彼德森图没有哈密顿圈,不是哈密顿图。它每点度都是 3,也不是欧拉图。

回溯搜索实验

按课件的算法(邻接表按字母排序)一步步搜索哈密顿通路。橙色是当前路径,蓝色虚线表示找到的通路能闭合成哈密顿圈。彼德森图回溯最明显。

哈密顿图的充分条件

既然没有简单的充要条件,就退而求其次:给出"只要满足就一定是哈密顿图"的条件。共同的直觉是:边越多、每个点的度越大,越容易找到哈密顿圈。

定理(Dirac,充分条件,课件第 52–56 页)

对于 n ≥ 3 的简单图 G,如果 G 的最小度

δ(G) ≥ n / 2

那么 G 是哈密顿图。(δ(G) 是 G 的顶点度数的最小值。)

证明(反证法 + "极大"反例):

  1. 构造一个"极大"的反例。假设定理不成立,有满足条件的非哈密顿图。往里面不断加边,只要加完仍不是哈密顿图就继续加。加边不会让度变小,条件 δ ≥ n/2 一直满足;而 Kn(n ≥ 3)是哈密顿图,所以加边过程一定在某处停下。停下时得到的 G 满足:G 不是哈密顿图,但再加任何一条边都会变成哈密顿图。这就是课件说的"极大非哈密顿简单图"。显然 G 不是完全图。
  2. 得到一条哈密顿路。取两个不相邻的顶点 u、v。由极大性,G + uv 是哈密顿图,而且它的每个哈密顿圈都必须用到新边 uv(否则这个圈在 G 里就存在了)。把这个圈里的 uv 去掉,得到 G 中一条从 u 到 v 的哈密顿路:
    P = v1v2 ⋯ vn, v1 = u,vn = v
  3. 定义两个下标集合。
    S = { vi | uvi+1 ∈ E(G) }, T = { vi | viv ∈ E(G) }
    S 是"u 的每个邻居在路上的前一个点"组成的集合,T 是 v 的邻居集合。u 的每个邻居 vi+1 对应 S 中唯一的 vi,所以 |S| = d(u);|T| = d(v)。
  4. |S ∪ T| < n。S 中的点下标 i ≤ n−1(因为 vi+1 要存在),所以 vn ∉ S;v 不和自己相邻,所以 vn ∉ T。S ∪ T 最多包含 v1, …, vn−1,|S ∪ T| ≤ n−1 < n。
  5. S ∩ T = ∅。否则设 vi ∈ S ∩ T,即 uvi+1 ∈ E 且 vivn ∈ E。那么
    v1 → vi+1 → vi+2 → ⋯ → vn → vi → vi−1 → ⋯ → v1
    是 G 中经过所有点的圈(下图),G 是哈密顿图,与假设矛盾。(课件第 55 页写成 "|S ∩ T| = ∅",应为 S ∩ T = ∅,即 |S ∩ T| = 0。)
  6. 导出矛盾。
    d(u) + d(v) = |S| + |T| = |S ∪ T| + |S ∩ T| < n + 0 = n
    但 δ(G) ≥ n/2 意味着 d(u) + d(v) ≥ n/2 + n/2 = n,矛盾!∎
v₁=uv₂v₃vᵢvᵢ₊₁vₙ₋₁vₙ=v
两条橙色弧 uvi+1、viv 加上路径的其余部分,去掉灰色的边 vivi+1,正好绕成一个哈密顿圈
证明真正用到的是什么

回头看,第 6 步只用到了"不相邻的 u、v 满足 d(u) + d(v) ≥ n"。所以同一个证明其实证明了更强的 Ore 定理:n ≥ 3 的简单图中,若任意两个不相邻的结点度数之和 ≥ n,则 G 是哈密顿图。Dirac 定理是它的特例。课件第 57 页的第二条("每一对节点的次数之和大于等于 n,则存在哈密顿圈")就是这个结论。

充分条件不是必要条件不满足这些条件的图也可能是哈密顿图。最简单的例子是圈 Cn(n ≥ 5):每点度只有 2 < n/2,但它本身就是一个哈密顿圈。所以这些定理只能用来证明某图是哈密顿图,不能用来否定。

定理 11.2.5:哈密顿链的充分条件

定理 11.2.5(课件第 57–60 页)

设 G 是具有 n(n ≥ 3)个结点的无向简单图。若 G 中每一对结点的度数之和 ≥ n − 1,则 G 中存在一条哈密顿链。

条件比 Dirac 弱了 1(n−1 而不是 n),结论也弱一些:只保证哈密顿链,不保证闭合成圈。证明分三步。

1. G 是连通的(反证法)。若不连通,至少有两个分支 G1、G2,各取一点 u ∈ G1、v ∈ G2。u 的邻居只能在 G1 里,d(u) ≤ |G1| − 1,同理 d(v) ≤ |G2| − 1。于是 d(u) + d(v) ≤ |G1| + |G2| − 2 ≤ n − 2,与条件矛盾。(这和 10.6 节"连通的充分条件"是同一个结论。)

2. 取最长的基本路径,证明它能闭合成圈。设 Γ = v1v2 ⋯ vl 是 G 中最长的基本路径(点不重复)。如果 l = n,它就是哈密顿链,证毕。下面设 l < n,证明存在一个经过 v1, …, vl 全部 l 个点的圈。

  • (i) v1 与 vl 相邻:Γ 加上边 (v1, vl) 就是这样的圈。
  • (ii) v1 与 vl 不相邻:
    • Γ 是最长的,所以 v1、vl 只能和 Γ 上的点相邻(如果 v1 有一个 Γ 外的邻居 w,把 w 接在前面就得到更长的基本路径)。
    • 设 v1 与 vi1, vi2, …, vik 相邻,共 k = d(v1) 个点。
    • vl 不能和任何 vij−1 相邻,否则下面就是经过 Γ 全部点的圈(和上面 Dirac 证明里的交叉弧完全一样),已经找到了:
      v1 → vij → ⋯ → vl → vij−1 → ⋯ → v1
    • 所以如果圈不存在,vl 的邻居只能在 v1, …, vl−1(l − 1 个点)中,并且要去掉这 k 个"禁区"点,最多 l − 1 − k 个。
    • 于是 d(v1) + d(vl) ≤ k + (l − 1 − k) = l − 1 < n − 1,与条件矛盾。所以圈一定存在。

3. 扩展路径,导出矛盾。现在有一个经过 Γ 上全部 l 个点的圈 C,而 l < n,所以 Γ 外还有点。G 连通,所以一定有 Γ 外的点 v 与 C 上某点 vj 相邻(一个圈 + 一个点)。从 v 出发走到 vj,再沿 C 绕一圈(不闭合),得到一条有 l + 1 个点的基本路径,比 Γ 还长,与"Γ 最长"矛盾。所以 l = n,Γ = v1v2 ⋯ vn 是哈密顿链。∎

课件第 57 页还列了两条相关结论:每一对结点度数之和 ≥ n 时存在哈密顿圈(上面的 Ore 定理);有向完全图(竞赛图)中必存在哈密顿通路(勒代定理,见 10.6 节)。课件特别强调:这些定理都是充分条件。

拓展:怎样证明一个图不是哈密顿图(课件未讲,考试常用)

有一个简单的必要条件:若 G 是哈密顿图,则对 V 的任意非空子集 S,删去 S 后的分支数 W(G − S) ≤ |S|。理由:哈密顿圈 C 删去 |S| 个点,最多断成 |S| 段,而 G − S 包含 C − S 的所有点和边,分支只会更少。

用法是找一个反例 S:例如领结图,删去中间 1 个点得到 2 个分支,2 > 1,所以不是哈密顿图;K2,3 删去左边 2 个点,剩下 3 个孤立点,3 > 2,也不是。注意它同样只能用来否定。彼德森图满足这个条件,却不是哈密顿图,只能靠更细的论证或者像课件那样用程序穷举。

✓

自测

点选项即判对错并显示解析。每题只能选一次,刷新页面可重来。

得分 0 / 0
∑

公式与易错点速查

公式

内容结论
握手定理∑d(v) = 2m;有向 ∑di = ∑do = m;奇度点个数为偶数
Knn 点,n(n−1)/2 边,(n−1) 正则
Cnn 点,n 边,2 正则
Wn(课件记法)n 点,2(n−1) 边;圈上点度 3,中心度 n−1
Km,nm+n 点,mn 边
Qn2n 点,n·2n−1 边,n 正则,二部图
Sm(0-1 序列图)2m 点,2m+1 条有向边,入度 = 出度 = 2
彼德森图10 点,15 边,3 正则
r 正则图存在r ≤ n−1 且 nr 为偶数
补图|E| + |E(~G)| = n(n−1)/2,d(v) + d~G(v) = n−1
自补图n ≡ 0, 1 (mod 4),边数 n(n−1)/4
无三角形图边数 ≤ ⌊n²/4⌋,K⌊n/2⌋,⌈n/2⌉ 取等
Ak(Ak)ij = i 到 j 长度为 k 的通路数;简单图 (A²)ii = d(vi)
可达矩阵R = B(I + A + ⋯ + An−1) = B[(I+A)n−1]
距离矩阵dij = 使 akij > 0 的最小 k(0 ≤ k < n),没有则 ∞
二部图⇔ 无奇数长回路 ⇔ 奇数 k 时 Ak 对角线全 0
通路长度可达 ⇒ 存在长度 ≤ n−1 的基本通路
有向连通强连通 ⇔ 有完备回路;单向连通 ⇔ 有完备通路;强 ⇒ 单向 ⇒ 弱
竞赛图勒代定理:一定有有向哈密顿通路
分支极大连通子图;连通 ⇔ 恰 1 个分支;强分支把结点分干净,单向分支可重叠
连通 ⇔ 划分G 连通 ⇔ V 的任意划分 {V₁,V₂} 都有跨边
回路(图)连通 2 度正则图;⇔ |V| = |E| 且能从 v 一笔走完所有点和边回到 v
有向回路判定有子图每点出度(或入度)> 0 ⇒ 有有向回路;W-过程删出度或入度为 0 的点
非循环图无向无回路 / 有向无半回路;反复删度 ≤ 1 的点能删成平凡图
连通的充分条件简单图任两点度数和 ≥ n−1,或每点 d(v) ≥ (n−1)/2 ⇒ 连通
分支数与边数m ≤ (n−k)(n−k+1)/2,k−1 个孤立点 + Kn−k+1 取等
点割集 / 边割集删掉后不连通,且少删任意一个都仍连通;单元素时叫割点 / 割边(桥)
割点、割边v 是割点 ⇔ 存在 u、w,每条 u–w 路都过 v;e 是桥 ⇔ e 不在任何圈上
Tarjan树枝边 (u,v) 是桥 ⇔ dfs[u] < low[v];复杂度 O(|V|+|E|)
支配集没选中的点都和选中的点相邻;无孤立点时,极小支配集的补集里还有另一个极小支配集
覆盖集 / 独立集(课件)都是边集:覆盖所有点的边 / 两两不相邻的边(匹配)
点覆盖NP 难;2-近似:|A| = 2|E′| ≤ 2|OPT|;二部图上 = 最大匹配(König)
欧拉图连通图:欧拉图 ⇔ 所有点度为偶数 ⇔ 若干边不重的圈的并
欧拉链连通且恰有两个奇点 u、v ⇔ 有 u 到 v 的欧拉链(加一条边 uv 化为欧拉回路)
一笔画口诀0 个奇点:回路;2 个奇点:链,从奇点出发;4 个以上:画不成
有向欧拉回路弱连通且每点入度 = 出度
Fleury沿未走过的边走,优先非桥边,除非只剩一条
中国邮递员奇点两两配对沿最短路重复,取最小;管梅谷:每边至多重复一次,每个圈上重复边总权 ≤ 圈长一半
哈密顿图有经过每点恰好一次的圈;NP 完全,无简单充要条件;回溯搜索
Dirac / Oreδ(G) ≥ n/2 ⇒ 哈密顿图;不相邻两点度和 ≥ n ⇒ 哈密顿图(n ≥ 3,简单图)
定理 11.2.5每对点度和 ≥ n−1 ⇒ 有哈密顿链
哈密顿必要条件删去任意 k 个点,分支数 ≤ k(只能用来否定)
课件运行结果十二面体从 a 出发 162 条哈密顿通路,60 条可闭合;彼德森图共 240 条,0 条可闭合

易错点

  1. 自环对度数贡献 2;邻接矩阵对角线记 1 个自环,算度时要乘 2。
  2. 有向简单图允许 ⟨u,v⟩ 与 ⟨v,u⟩ 同时存在,它们不是平行边。
  3. 同构的必要条件(点数、边数、度数序列)只能用来否定同构。要肯定同构必须给出双射并验证。
  4. Wn 的下标在不同教材里指"总点数"或"圈上点数",先确认定义。
  5. 生成子图看"点全不全",导出子图看"选中点之间的边全不全"。
  6. 补图只对简单图定义,参照物是同阶的 Kn。
  7. 可达矩阵别忘了加 I,也别忘了最后布尔化;课件 Python 输出的大数是 (I+A)n−1 原值。
  8. 有向图的距离不对称,可达也不对称。
  9. "简单"管边不重复,"基本"管点不重复;基本 ⇒ 简单。
  10. 完备通路/回路允许点重复,它和"每个点恰好一次"的哈密顿通路/回路不是一回事。
  11. "G 有一条回路"指走法,"G 是回路"指图本身是一个圈(连通 2 度正则)。
  12. 有向图"没有有向回路"不等于"非循环图",后者要求连半回路都没有。
  13. "极小 / 极大"是不能再减 / 不能再加,"最小 / 最大"是个数最少 / 最多,前者不一定是后者。
  14. 点割集和边割集都要求"极小":删掉能断开,但少删任何一个都断不开。
  15. 有割点不一定有割边(领结图)。
  16. 本课件的覆盖集、独立集是边集;"最小点覆盖"是点集。看清选的是点还是边。
  17. Tarjan 判桥用 dfs[u] < low[v],判割点用 dfs[u] ≤ low[v](根结点另判)。
  18. 欧拉看边(每条边恰好一次,点可重复),哈密顿看点(每点恰好一次,边不必走完)。两者互不蕴含。
  19. "欧拉圈"允许点重复,不是 10.7 节"点不重复"的圈。
  20. 判断欧拉图前先确认连通;奇点个数一定是偶数,不会出现 1 个或 3 个。
  21. Fleury 里的"桥"是指剩余图(擦掉已走过的边)中的桥,不是原图中的桥。
  22. Dirac、Ore、定理 11.2.5 都是充分条件,不满足不代表不是哈密顿图(例如 Cn)。
  23. 度数和 ≥ n−1 只保证哈密顿链,≥ n 才保证哈密顿圈。