【线性平面图判定算法】

本文介绍了Hopcroft和Tarjan在1974年提出的平面图判定算法,该算法能在O(V)时间内判断一个图是否为平面图。通过理解dfs树、返祖边、双连通图等概念,结合定理和具体步骤,逐步解释了算法思想和实现细节,包括边的排序、路径查找、路径嵌入等,最终实现了高效的空间和时间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

由于离散课需要回课,就去学了Hopcroft和Tarjan老爷子在1974年提出的 O ( V ) O(V) O(V) 时间内判断一个图是否是平面图的算法,然后上课的时候讲。原文是 John Hopcroft and Robert Tarjan. 1974. Efficient Planarity Testing.J. ACM21, 4 (October 1974), 549-568. 这是链接

用了好一些时间才完全理解整个算法。想懂之后其实并不难,但真真实实非常巧妙。

感觉论文读起来困难是因为一开始没有把握到算法的整体思想,所以一度看的怀疑人生。一旦知道文章在干嘛,很多地方读起来就十分自然了。

课上听某同学讲,某年清华集训貌似就出了一道平面图判定的模板题,也不清楚标算是不是用的这个算法。

一些记号

简单路径:每个点至多被经过一次。

环:除起点外,每个点至多被经过一次。

割点:删掉该点后原图不再连通。

双连通图:连通且不包含割点的图。

p : v ⇒ ∗ w p:v\Rightarrow ^* w p:vw p p p 是一条从 v v v w w w 的路径。

树:根为 r r r 的有向图 T T T,从 r r r 出发可以到达所有点, r r r 没有入边,其余每个点恰好有一条入边。

v → w v\to w vw T T T 中一条 v v v w w w 的边,称 v v v w w w 的父亲, w w w v v v 的儿子。

v → ∗ w v\to ^* w vw T T T v v v w w w 的路径,称 v v v w w w 的祖先, w w w v v v 的后代。

d f s dfs dfs

G G G 是一个连通无向图。从一个点开始对 G G G d f s dfs dfs,令经过的边为树边,得到 G G G 的生成树 T T T,称 T T T G G G d f s dfs dfs 树。

若边 ( v , w ) (v,w) (v,w) 不是树边,且 v v v w w w T T T 中有祖先关系,不妨设 w w w v v v 的祖先,则称 ( v , w ) (v,w) (v,w) 为一条返祖边,记为 v − → w v-\to w vw

因为是通过 d f s dfs dfs 遍历图 G G G,所以 G G G 中的每一条非树边必然是返祖边。

d f n ( x ) dfn(x) dfn(x) 表示 x x x 被到达的时刻, l o w ( x ) low(x) low(x) 表示通过 x x x 的子树中的返祖边能到达的节点的 d f n dfn dfn 的最小值,形式化定义就是 l o w ( x ) = min ⁡ { d f n ( x ) , min ⁡ ( u , v ) ∈ E f , u ∈ s u b t r e e ( x ) d f n ( v ) } low(x)=\min\{dfn(x),\min_{(u,v)\in E_f,u\in subtree(x)}dfn(v)\} low(x)=min{ dfn(x),(u,v)Ef,usubtree(x)mindfn(v)}

其中 E f E_f Ef 表示返祖边构成的集合。同时令 l o w 2 ( x ) low2(x) low2(x) 表示次小值。

算法思想

对于一个连通图 G G G,它是平面图当且仅当它的每一个点双连通分量均为平面图。因此只需要考虑一个双连通图的平面图判定问题。

先找出 G G G d f s dfs dfs T T T,将每个点 x x x 重标号为 d f n ( x ) dfn(x) dfn(x),并将边重定向:令树边从父亲指向儿子,返祖边从后代指向祖先。找到 G G G 中的一个环 c : 1 → v 1 → v 2 → ⋯ → v n − → 1 c:1\to v_1\to v_2\to \cdots\to v_n-\to 1 c:1v1v2vn1,环中只有最后一条边是返祖边。删掉 c c c 后会得到很多个连通块,称之为 segment。每个 segment 要么是一条 v i → ∗ v j v_i\to^*v_j vivj 的返祖边,要么由某个 v i v_i vi 的儿子 u u u 的子树中的所有边(包括返祖边)组成。则每个 segment 最后必然全落在 c c c 的内侧或外侧。

每个 segment 都对应一个环 c u : v i → u ⇒ ∗ l o w ( u ) → ∗ v i c_u:v_i\to u\Rightarrow ^*low(u)\to ^*v_i cu:viulow(u)vi,可将 c u c_u cu 看作该 segment 的外轮廓。按照从外向内的顺序嵌入 segment,则该 segment 的其他部分可被嵌入到 c u c_u cu 的内部,不影响其他已经被嵌入的 segment。

对于一个新加入的 segment,先考虑在已经嵌入了环 c c c 和前面被加入的 segment 的基础上,其外轮廓能否被嵌入到平面中。若不能嵌入,则 G G G 不是平面图。否则保留 c u c_u c

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值