参考资料
定义们
记 N ( u ) N(u) N(u) 为 u u u 的所有的邻居构成的集合。对于一个点集 S S S,定义 N ( S ) N(S) N(S) 为 { x ∣ ∀ v ∈ S , x ∈ N ( v ) } \{ x\mid \forall v\in S, x\in N(v)\} { x∣∀v∈S,x∈N(v)}。
弦图 (chordal graph):满足任意一个长度大于 3 的环都有弦的图。
单纯点 (simplicial vertex):如果 N ( u ) N(u) N(u) 的导出子图为团,就称 u u u 为单纯点。
完美消除序列 (perfect elimination ordering):称 G G G 的结点的一个排列 { v 1 , v 2 , ⋯ v n } \{v_1,v_2,\cdots v_n\} { v1,v2,⋯vn} 为 G G G 的完美消除序列,当且仅当对于每一个 i i i , v i v_i vi 在 v i , v i + 1 , ⋯ v n v_i,v_{i+1},\cdots v_n vi,vi+1,⋯vn 的导出子图中是单纯点。
下文中,称完美消除序列的逆序为单纯消除序列 (simplicial elimination ordering)(这个中文名称是我编的,因为没有在网上找到相应的中文资料),也就是满足 v i v_i vi 在 v 1 , v 2 , ⋯ v i v_1,v_2,\cdots v_i v1,v2,⋯vi 的导出子图中为单纯点的排列。
一个定理
引理 1:弦图的任意导出子图也是弦图。
引理 2:任何弦图都至少有一个单纯点;不是完全图的弦图至少有两个不相邻的单纯点。
定理: G G G 是弦图当且仅当 G G G 存在完美消除序列。
完美消除序列判定
判断一个序列是否为完美消除序列。
设 v i v_i vi 在 v i + 1 , v i + 2 ⋯ v n v_{i+1},v_{i+2}\cdots v_n vi+1,vi+2⋯vn 中相邻的点按照它们在序列中出现的顺序依次为 v c 1 , v c 2 , ⋯ v c k v_{c_1},v_{c_2},\cdots v_{c_k} vc1,vc2,⋯vck,只需要判断 v c 1 v_{c_1} vc1 与其它点是否相邻即可。
正确性证明:假设已知 v i + 1 , v i + 2 , ⋯ v n v_{i+1},v_{i+2},\cdots v_n vi+1,vi+2,⋯vn 是合法的完美消除序列的后缀,那么由于 v c 1 v_{c_1} vc1 在 { v c 1 , v c 1 + 1 , ⋯ v n } \{v_{c_1},v_{c_1+1},\cdots v_n\} { vc1,vc1+1,⋯vn} 的导出子图中为单纯点,如果 v c 1 v_{c_1} vc1 与 v c 2 , v c 3 , ⋯ v c k v_{c_2},v_{c_3},\cdots v_{c_k} vc2,vc3,⋯vck 都相邻,那么 v c 2 , v c 3 , ⋯ v c k v_{c_2},v_{c_3},\cdots v_{c_k} vc2,vc3,⋯vck 一定形成团。
最大势算法
又称为maximum cardinality search algorithm、MCS algorithm。是用来求完美消除序列的一种算法。
算法流程
设图 G G G 的点集为 V V V;用 w e i g h t ( u ) weight(u) weight(u) 表示点 u u u 的权重。
- 初始化 W W W 为 V V V,并将 V V V 中所有点的权重置为 0 0 0
- 对 i = 1 , 2 , ⋯ n i=1,2,\cdots n i=1,2,⋯n ,执行以下过程
- 令 u u u 为此时 W W W 中权重最大的点
- 令 v i = u v_i = u vi=u
- 将 u u u 的所有邻居的权重增加 1 1 1
- 将 u u u 从 W W W 中删除
- 返回 { v 1 , v 2 , ⋯ v n } \{v_1,v_2,\cdots v_n\} { v1,v2,⋯vn}
用链表实现可以做到 O ( n + m ) O(n+m) O(n+m) 的复杂度。
可以证明,当 G G G 为弦图时,MCS 算法返回的序列是 G G G 的单纯消除序列。
正确性证明
令 V i = { v , v 2 , ⋯ v i } V_i = \{v_,v_2,\cdots v_i\} Vi={ v,v2,⋯vi} ;令 W i W_i Wi 为第 2 步进行了 i i i 次之后的 W W W ;令 w e i g h t i ( v ) weight_i(v) weighti(v) 表示第 2 步进行了 i i i 次之后 v v v 点的权重;令 a ≺ b a \prec b a≺b 表示在返回的序列中 a a a 在 b b b 的前面。
我们通过证明以下循环不变式来证明命题:
- v i v_i vi 在 V i V_i Vi 的导出子图中为单纯点
- 令 S S S 为 V V V 的一个子集,其中的每个点 v x v_x vx 都满足 v x v_x vx 在 V x V_x Vx 的导出子图中为单纯点;对于两个点 a , v i ∈ N ( S ) − S a,v_i \in N(S) - S a,vi∈N(S)−S ,如果 a ≺ v i a\prec v_i a≺vi 且 N ( S ) − S N(S)-S N(S)−S 中存在一条从 a a a 到 v i v_i vi 的路径,那么 N ( S ) − S N(S)-S N(S)−S 中存在一条从从 a a a 到 v i v_i vi 且经过的所有点都满足 ≺ v i \prec v_i ≺vi 的路径
证明 1.
考虑反证:假设 v i v_i vi 在 V i V_i Vi 的导出子图中不是单纯点,那么必定存在 v j , v k ∈ N ( v i ) ∩ V i − 1 v_j,v_k\in N(v_i)\cap V_{i-1} vj,vk∈N(vi)∩Vi−1 满足 j < k < i , v k ∉ N ( v j ) j< k < i, v_k\notin N(v_j) j<k<i,vk∈/N(vj)。