Category Archives: Graph Theory

深度优先搜索中图的边

原载于 2013-07-12

最后修改于 2013-10-06

注:当时应该是有人在评论中指出了本文的一个错误,于是便有了第二版的修改,不过评论估计是无法找回了。

 


 

在一些算法中我们经常需要用到DFS树的性质。我们在这里DFS中原图边的类型进行一些归纳总结,方便诸位对DFS树加深理解。

 

原图中的边一共分为四种类型:

(1)树边(tree edge)

搜索树中存在的边。

(2)前向边(forward edge)

将节点u与其在搜索树中的后代(descendant)v相连的非树边。

(3)后向边(back edge)

将节点u与其在搜索树中的祖先(ancestor)v相连的非树边。

(4)交叉边(cross edge)

其他不属于以上三类的边。

 

大家可以看到,上面四种边的定义涉及到了边与搜索树的关系。所以这里所说的原图中的边都是相对搜索树而言的,也就是说只有在搜索树确定了之后,讨论这四种边才是有意义的。

我们对无向图与有向图分别进行讨论。

1.无向图

考虑下图:

20130712080004_82593

其对应的一种搜索树(森林)为:

20130712080537_30727

 

蓝紫色带箭头的边为树边,表示的是DFS中递归调用的轨迹。由于无向图中前向边和后向边可以认为是等价的,所以红色、黄色虚线边既是前向边也是后向边。

无论以什么样的顺序进行DFS,无向图中都不会存在交叉边。例如假设4、6之间存在一条边(原图中蓝色虚线表示)。若4先于6被访问,那末,在访问4的时候,发现6没有被访问,则会于此对6进行访问,此时形成了父子关系;若6先被访问,则亦然。

边类型的判定

无向图中边类型的判定较为简单。树边就是递归调用经过的边。判断前向/后向边,则只需利用DFS记录顶点是否访问的标记。在访问某个顶点时,若发现一条边与另一个非父节点的已访问节点的相连,则这条边是后向边。

 

 

2.有向图

有向图中的情况则复杂一些。

考虑下图:

20130712080646_64355

 

其对应的一种搜索树(森林)为:

20130712080711_38196

 

蓝紫色边仍然是树边。此时,由于原图中(3, 1)变为了有向边,红色虚线边仅为后向边;同理,由于边(1, 4)有向,黄色虚线边仅为前向边。灰色虚线边则是交叉边。

 

边类型的判定

有向图中,由于边的类型较为复杂,无法直接根据顶点是否访问来进行判定。故需要维护每一个顶点的前序时间戳(Preordering)与后序时间戳(Postordering)。某个顶点的前序时间戳Pre[v]在到达这个顶点尚未进行任何操作时记录,后序时间戳Post[v]则在这个顶点访问完,弹栈之前记录。

据分析可得出以下判定规律:

(1) 递归调用轨迹边为树边。

(2) 对于非树边(u, v),若有Pre[u]<Pre[v]且Post[u]>Post[v],则(u, v)为前向边。

(3) 对于非树边(u, v),若有Pre[u]>Pre[v]且Post[u]<Post[v],则(u, v)为后向边。

(4) 对于非树边(u, v),若有Pre[u]>Pre[v]且Post[u]>Post[v],则(u, v)为交叉边。

(5) 不存在这样的边(u, v),使得Pre[u]<Pre[v]且Post[u]<Post[v]。