图论研究的是:
对象之间的连接关系比如:
- 城市之间有没有路;
- 人和人之间是否认识;
- 程序是否等待某个资源;
- 任务之间谁必须先完成;
- 两个点之间最短路线是多少。
图的基本结构就是:
G=⟨V,E,φ⟩其中:
| 符号 | 含义 |
|---|
| V | 顶点集 |
| E | 边集 |
| φ | 关联函数,说明每条边连接哪些顶点 |
最直观一句话:
顶点表示对象,边表示对象之间的关系
图通常记作:
G=⟨V,E,φ⟩其中:
- V 是非空有限集合,元素叫顶点;
- E 是有限集合,元素叫边;
- φ 把每条边对应到某个顶点对。
如果边没有方向,叫无向图。
如果边有方向,叫有向图。
无向边连接两个顶点,不分起点终点。
如果边 e 连接 u,v,可以写作:
e=(u,v)或者理解成无序对:
u,v例如:
u−v表示 u 和 v 相连。
有向边有方向,有起点和终点。
如果边从 u 指向 v,记作:
e=⟨u,v⟩其中:
画图时用箭头表示:
u→v
图中的点叫顶点,也叫结点。
例如:
V=v1,v2,v3表示图有三个顶点。
图中连接顶点的线叫边。
无向图的边没有方向。
有向图的边有方向。
如果边 e 连接顶点 u 和 v,则称:
边 e 与顶点 u,v 关联。
也说 u,v 是边 e 的端点。
如果两个顶点之间有边相连,就称它们是邻接顶点。
例如:
(u,v)∈E则 u 和 v 邻接。
如果两条边有公共端点,则称它们是邻接边。
比如:
e1=(u,v),e2=(v,w)它们都经过 v,所以 e1,e2 邻接。
一条边的两个端点相同,叫自环。
形式:
e=(v,v)画图时就是顶点上绕一圈的边。
如果两个顶点之间有多条边相连,这些边叫重边。
例如:
e1=(u,v),e2=(u,v)且 e1=e2,它们就是重边。
如果某个顶点没有任何边与它关联,则称它是孤立点。
孤立点的度为 0。
只含一些孤立点、没有边的图,叫零图。
也就是:
E=∅
只有一个孤立顶点的图,叫平凡图。
含有重边的图叫多重图。
教材里含重边的图称为多重边图。
不含自环,也不含重边的图,叫简单图。
简单图 = 无自环 + 无重边这是后面讨论很多定理时最常用的图。
如果一个简单图中任意两个不同顶点之间都有边相连,则叫完全图。
含 n 个顶点的无向完全图记作:
Kn无向完全图的边数是:
2n(n−1)因为 n 个顶点中任意选两个顶点连一条边:
Cn2=2n(n−1)如果是有向完全图,每一对不同顶点之间有两个相反方向的有向边,则边数是:
n(n−1)
在无向图中,一个顶点 v 的度,记作:
d(v)表示与 v 关联的边数。
注意:
自环对度的贡献是 2因为自环的两个端点都在同一个顶点上。
在有向图中:
从顶点 v 发出的边数叫出度,记作:
d+(v)进入顶点 v 的边数叫入度,记作:
d−(v)d(v)=d+(v)+d−(v)
如果:
d(v)是奇数,则 v 是奇顶点。
如果:
d(v)是偶数,则 v 是偶顶点。
如果无向图中所有顶点的度都等于 k,则称它是 k 正则图。
例如:
- 所有顶点度都是 2:2 正则图;
- 所有顶点度都是 3:3 正则图。
这是本章最重要公式之一。
设无向图 G=⟨V,E⟩,边数为 m,则:
v∈V∑d(v)=2m意思是:
所有顶点度数之和 = 边数的 2 倍。
为什么?
因为每条普通边贡献两个端点,自环也贡献 2。
因为:
v∈V∑d(v)=2m一定是偶数。
偶数度顶点加起来还是偶数,所以奇数度顶点的个数必须是偶数。
结论:
任意无向图中,奇顶点个数为偶数这条非常常考。
设:
G=⟨V,E⟩,G′=⟨V′,E′⟩如果:
V′⊆V,E′⊆E则 G′ 是 G 的子图。
如果 G′ 是 G 的子图,但:
V′=V或:
E′=E则称 G′ 是 G 的真子图。
如果:
V′=V但:
E′⊆E则称 G′ 是 G 的生成子图,也叫支撑子图。
意思是:
顶点全保留,只删一些边。
如果取:
V′⊆V并保留 V′ 中顶点之间在原图中所有的边,则得到的子图叫顶点导出子图,记作:
G[V′]通俗说:
选一些顶点,把这些顶点之间原来有的边全部保留。
如果取:
E′⊆E并把这些边及其端点组成子图,则叫边导出子图,记作:
G[E′]
从图 G 中删去顶点 v,同时删去与 v 关联的所有边,记作:
G−v如果删去顶点集合 V′,记作:
G−V′
从图中删去边 e,记作:
G−e从图中删去边集 E′,记作:
G−E′
如果在图中加入边 e,记作:
G+e
补图的意思是:
原图没有的边,在补图里有;原图有的边,在补图里没有。
设 G 是含 n 个顶点的简单图,则 G 的补图记作:
G它的顶点集和 G 相同。
并且:
uv∈E(G)当且仅当:
uv∈/E(G)也就是说:
G+G=Kn
两个图 G 和 G′ 如果只是“画法不同”,但结构完全一样,就叫同构。
严格说,如果存在一个顶点双射:
f:V(G)→V(G′)并且保持邻接关系,则称 G 与 G′ 同构,记作:
G≅G′
如果两个图同构,必须保持:
- 顶点数相同;
- 边数相同;
- 度数序列相同;
- 邻接关系相同;
- 有向图还要保持方向;
- 自环、重边数量也要对应。
也就是说:
顶点数相同、边数相同、度数序列相同只能说明它们可能同构,不能保证一定同构。
判断不同构时,常用方法是找不变量不同。
例如:
- 一个有孤立点,另一个没有;
- 一个有三角形,另一个没有;
- 一个有自环,另一个没有;
- 一个连通,另一个不连通。
这一节研究“能不能从一个顶点走到另一个顶点”。
设:
G=⟨V,E⟩一个路径可以写成:
μ=v0e1v1e2v2⋯ekvk意思是:
从 v0 出发,经过边 e1,e2,…,ek,最后到达 vk。
路径长度是边数:
k
在:
μ=v0e1v1⋯ekvk中:
- v0:起点;
- vk:终点;
- k:路径长度。
如果路径中的边互不相同,则称为简单路径。
教材中“简单路径”重点看边不重复。
如果路径中的顶点互不相同,则称为基本路径,也常叫通路。
顶点不重复自然边也不会重复,所以:
基本路径一定是简单路径但简单路径不一定是基本路径。
如果路径的起点和终点相同:
v0=vk则称为循环,也常叫回路。
如果循环中的边互不相同,则称为简单循环。
如果除了起点和终点相同之外,其余顶点互不相同,则称为基本循环。
基本循环一定是简单循环但简单循环不一定是基本循环。
设 G 是含 n 个顶点的有向图。
任意基本路径的长度最多为:
n−1因为基本路径不能重复顶点。
如果有 n 个顶点,最多经过 n 个顶点,因此最多有 n−1 条边。
任意基本循环的长度最多为:
n因为基本循环除了起点终点相同外,其他顶点不重复。
在有向图中,如果从顶点 u 到顶点 v 存在路径,则称:
v从:
u可达。
也可以说:
u→v可达。
规定任意顶点到自己都是可达的。
所以可达关系具有自反性。
如果:
u可达:
v并且:
v可达:
w则:
u可达:
w所以可达关系是自反、传递的。
在有向图中,两个顶点 vi,vj 的距离记作:
d[vi,vj]定义如下:
- 如果 i=j,则:
d[vi,vj]=0- 如果 vj 从 vi 不可达,则:
d[vi,vj]=∞- 如果 vj 从 vi 可达,则:
d[vi,vj]等于从 vi 到 vj 的最短路径长度。
一般:
d[vi,vj]=d[vj,vi]因为有向边有方向。
设 G 是无向图。
如果任意两个顶点之间都有路径相连,则称 G 是连通图。
如果无向图不连通,可以分成若干个极大连通子图。
这些极大连通子图叫连通分支。
连通分支个数记作:
ω(G)如果 G 是连通图,则:
ω(G)=1
如果删去某条边后,图的连通分支数增加,则这条边叫割边,也叫桥。
即:
ω(G−e)>ω(G)则 e 是割边。
直观理解:
一删这条边,图就更散了。
如果删去某个顶点以及与它关联的边后,图的连通分支数增加,则这个顶点叫割点。
即:
ω(G−v)>ω(G)则 v 是割点。
有向图比无向图复杂,教材分三种:
如果任意两个顶点 u,v,都有:
u 可达 v并且:
v 可达 u则称有向图是强连通图。
通俗说:
任意两个点之间都能双向到达。
如果任意两个顶点 u,v,至少有一个方向可达:
u 可达 v或:
v 可达 u则称为单向连通图。
如果把有向图中所有边的方向去掉后,得到的无向图是连通图,则称原有向图是弱连通图。
强连通⇒单向连通⇒弱连通反过来一般不成立。
也就是说:
有向图中的极大强连通子图叫强分图。
有向图中的极大单向连通子图叫单向分图。
有向图中的极大弱连通子图叫弱分图。
对于有向图:
- 每个顶点恰好属于一个强分图;
- 每个顶点和每条边至少属于一个单向分图;
- 每个顶点和每条边恰好属于一个弱分图。
这一节很重要,因为它把图变成矩阵,方便计算机处理。
主要有:
- 关联矩阵;
- 邻接矩阵;
- 可达矩阵;
- 距离矩阵。
关联矩阵描述的是:
顶点和边之间的关系设:
V=v1,v2,…,vnE=e1,e2,…,em关联矩阵是一个:
n×m矩阵。
行对应顶点,列对应边。
无向图中:
F=(fij)n×m其中:
fij={0,ej 不关联 vi 1,ej 是非自环且关联 vi 2,ej 是自环且关联 vi解释:
- 普通边连接两个顶点,所以对应两行各有一个 1;
- 自环在一个顶点上贡献 2。
- 每一列元素和为 2;
- 每一行元素和等于对应顶点的度;
- 全 0 行对应孤立点;
- 重边对应相同的列。
有向图中,关联矩阵要体现方向。
一般按教材定义:
fij={0,ej 不关联 vi 1,ej 以 vi 为起点 −1,ej 以 vi 为终点 −2,ej 是关联 vi 的自环不同教材对有向自环的矩阵记法可能略有差异,但普通有向边最重要的是:
起点记 1, 终点记 −1
邻接矩阵描述的是:
顶点和顶点之间的连接关系设:
V=v1,v2,…,vn邻接矩阵是:
n×n矩阵。
有向图中:
A=(aij)n×n其中:
aij=k表示从 vi 到 vj 的有向边有 k 条。
如果没有边,则:
aij=0
无向图中:
aij=k表示 vi 和 vj 之间有 k 条边。
如果 G 是简单图,则:
- 主对角线元素全为 0;
- 每个元素只能是 0 或 1;
- 无向简单图的邻接矩阵是对称矩阵。
即:
A=AT
对于有向图:
d+(vi)=j=1∑naij也就是第 i 行元素之和。
d−(vi)=j=1∑naji也就是第 i 列元素之和。
d(vi)=d+(vi)+d−(vi)
这是很重要的计算结论。
设 A 是无重边有向图的邻接矩阵。
那么:
Am中第 i,j 个元素表示:
从 vi 到 vj 的长度为 m 的路径条数如果:
i=j则表示从 vi 出发又回到 vi 的长度为 m 的循环条数。
如果:
(A3)24=5表示:
从 v2 到 v4 的长度为 3 的路径有 5 条。
可达矩阵只关心:
能不能到达。
不关心有几条路径,也不关心路径长度。
设有向图 G 的可达矩阵为:
P=(pij)其中:
pij={1,i=j 或 vj 从 vi 可达 0,vj 从 vi 不可达
如果:
pij=1表示:
vi→vj可达。
如果:
pij=0表示不可达。
如果有 n 个顶点,则只需考虑长度不超过 n−1 的基本路径。
所以可以用布尔矩阵运算:
P=I∨A∨A(2)∨⋯∨A(n−1)其中:
- I:单位矩阵,表示自己到自己可达;
- A(k):布尔意义下的 k 次幂;
- ∨:布尔或。
也可以先求普通幂:
A+A2+⋯+An−1再把非零元素改成 1。
如果有可达矩阵 P,那么:
P∧PT可以表示互相可达关系。
如果:
pij=1且:
pji=1说明:
vi和:
vj互相可达,可能属于同一个强分图。
距离矩阵记录的是两个顶点之间最短距离。
设:
D=(dij)其中:
dij=d[vi,vj]如果不可达,则:
dij=∞如果:
i=j则:
dii=0
这一节主要讲图论应用。
教材里有几类:均分问题、最短路径问题、最优路径问题、关键路径问题。
这种题一般把“状态”看成顶点,把“一步操作”看成边。
比如三个容器倒水问题:
- 每一种水量分布是一个状态;
- 从一种状态倒水到另一种状态,就是一条边;
- 问能否均分,就是问图中是否存在从初始状态到目标状态的路径。
核心思想:
状态 = 顶点,操作 = 边,求解 = 找路径
如果图的每条边都赋有一个数值,称为赋权图,也叫带权图。
记边 e 的权为:
W(e)权可以表示:
在赋权图中,一条路径的长度不是边数,而是路径上所有边权之和。
如果路径:
μ=e1e2⋯ek则:
l(μ)=W(e1)+W(e2)+⋯+W(ek)
Dijkstra 算法用于求:
从一个源点到其他顶点的最短路径通常要求边权非负。
把顶点分成两类:
| 集合 | 含义 |
|---|
| P | 已确定最短路径的顶点 |
| T | 暂时未确定的顶点 |
初始时:
P=v0然后不断从 T 中选出当前距离最小的顶点,加入 P,并更新它的邻接点距离。
设源点为 v0。
d(v0)=0对于其他顶点:
d(vi)={W(v0,vi),v0 与 vi 有边 ∞,v0 与 vi 无边
从未确定顶点中选 d 值最小的顶点 vk,加入 P。
对 vk 的邻接顶点 vi,若:
d(vk)+W(vk,vi)<d(vi)则更新:
d(vi)=d(vk)+W(vk,vi)
一直重复,直到目标点被加入 P,或者所有顶点都加入 P。
Dijkstra 适合:
- 单源最短路径;
- 非负权图;
- 地图导航;
- 网络路由;
- 成本最小问题。
Floyd 算法用于求:
任意两点之间的最短路径也叫全源最短路径算法。
设初始距离矩阵为:
D(0)=(dij(0))其中:
dij(0)表示边 vi→vj 的权。
如果没有边:
dij(0)=∞如果:
i=j则:
dii(0)=0
Floyd 算法的核心是:
dij(k)=min(dij(k−1), dik(k−1)+dkj(k−1))意思是:
从 i 到 j 的最短路,要么不经过 k,要么经过 k。
如果经过 k 更短,就更新。
依次令:
k=1,2,…,n逐步允许路径经过更多中间顶点。
最终:
D(n)就是所有顶点对之间的最短距离矩阵。
| 算法 | 作用 |
|---|
| Dijkstra | 求一个源点到其他点的最短路径 |
| Floyd | 求任意两点之间的最短路径 |
一句话:
Dijkstra 是单源,Floyd 是全源
决策图是一类有向赋权图。
顶点分层:
V1,V2,…,Vs边只从前一层指向后一层。
这种图常用来表示多阶段决策问题。
从初始顶点到终止顶点的路径中,权值总和最小的路径叫最优路径。
求法通常是动态规划思想:
从后往前,逐层计算每个顶点到终点的最优值。
如果从 v 出发,可以走到若干后继顶点 u1,u2,…,uk,则:
F(v)=iminW(v,ui)+F(ui)意思是:
从当前点出发的最优值 = 走一条边的代价 + 后面最优值 的最小值。
PERT 图用于工程项目管理。
PERT 图是一种有向无环图。
- 顶点表示事件;
- 边表示任务;
- 边权表示完成任务所需时间;
- 有一个源点;
- 有一个汇点。
顶点 vi 的最早完成时间记作:
TE(vi)表示在不违反先后顺序的情况下,事件 vi 最早什么时候能发生。
通常:
TE(v1)=0对其他点:
TE(vi)=maxTE(vj)+W(vj,vi)其中 vj 是 vi 的前驱顶点。
顶点 vi 的最迟完成时间记作:
TL(vi)表示在不延误总工期的情况下,事件 vi 最晚什么时候必须发生。
终点:
TL(vn)=TE(vn)对其他点:
TL(vi)=minTL(vj)−W(vi,vj)其中 vj 是 vi 的后继顶点。
如果某条路径上的顶点都满足:
TE(v)=TL(v)则这条路径可能是关键路径。
关键路径的长度就是整个工程的最短完成时间。
关键路径上的任务不能延误。
只要关键路径上任一任务延误,整个项目就会延误。
非关键路径上的任务通常有一定机动时间。
| 知识点 | 公式 / 结论 |
|---|
| 无向完全图边数 | 2n(n−1) |
| 有向完全图边数 | n(n−1) |
| 握手定理 | ∑v∈Vd(v)=2m |
| 奇顶点个数 | 一定是偶数 |
| 基本路径最大长度 | n−1 |
| 基本循环最大长度 | n |
| 有向图出度 | d+(vi)=∑jaij |
| 有向图入度 | d−(vi)=∑jaji |
| 邻接矩阵幂 | (Am)ij 表示长度为 m 的路径条数 |
| 可达矩阵 | P=I∨A∨A(2)∨⋯∨A(n−1) |
| Floyd 更新 | dij(k)=min(dij(k−1),dik(k−1)+dkj(k−1)) |
| 路径权长 | l(μ)=∑W(ei) |
常问:
- 是无向图还是有向图?
- 是简单图还是多重图?
- 有没有自环?
- 有没有重边?
- 是不是完全图?
- 是不是正则图?
口诀:
简单图:无自环、无重边完全图:任意两点都有边
无向图中:
有向图中:
- 出边算出度;
- 入边算入度;
- 总度 = 出度 + 入度。
给出度数序列,问是否可能构成无向图。
先看:
∑d(v)是否为偶数。
如果是奇数,必不可能。
还要看是否违反简单图条件,比如某个顶点度数超过:
n−1
要看:
V′⊆V,E′⊆E生成子图看顶点是否全部保留。
导出子图看是否保留了对应的所有边。
先查:
- 顶点数;
- 边数;
- 度数序列;
- 是否连通;
- 是否有自环、重边;
- 是否有三角形、孤立点、割点等结构。
如果这些不同,肯定不同构。
如果都相同,还要进一步找顶点对应关系。
无向图:
任意两点有路径⇒连通有向图:
强连通⇒单向连通⇒弱连通
邻接矩阵:
n×n表示顶点和顶点关系。
关联矩阵:
n×m表示顶点和边关系。
如果题目问:
“从 vi 到 vj 长度为 m 的路径有几条?”
就看:
(Am)ij
用:
P=I∨A∨A(2)∨⋯∨A(n−1)或用 Warshall 类方法。
单源最短路径:
Dijkstra任意两点最短路径:
Floyd
| 名称 | 要求 |
|---|
| 路径 | 可以重复边、重复点 |
| 简单路径 | 边不重复 |
| 基本路径 | 顶点不重复 |
所以:
基本路径一定是简单路径,反之不一定
| 名称 | 要求 |
|---|
| 循环 | 起点终点相同 |
| 简单循环 | 边不重复 |
| 基本循环 | 除起点终点外,顶点不重复 |
强:双向可达单向:至少一个方向可达弱:去掉方向后连通
| 矩阵 | 行 | 列 | 表示 |
|---|
| 关联矩阵 | 顶点 | 边 | 顶点与边是否关联 |
| 邻接矩阵 | 顶点 | 顶点 | 顶点之间是否有边 |
| 算法 | 用途 |
|---|
| Dijkstra | 一个点到其他点 |
| Floyd | 所有点到所有点 |
第十二章就是图论入门,核心主线是:
图是什么图有哪些基本结构图中能不能走通如何用矩阵表示图如何解决最短路径和关键路径问题最该背的是:
v∈V∑d(v)=2m奇度顶点个数一定为偶数基本路径长度≤n−1(Am)ij 表示从 vi 到 vj 长度为 m 的路径数强连通⇒单向连通⇒弱连通Dijkstra 求单源最短路,Floyd 求任意两点最短路这章概念很多,但逻辑很清楚:先认识图,再研究走法,再用矩阵计算,最后拿去解路径问题。