POJ 2594 Treasure Exploration

题意

给出一个DAG(有向,没有环的图),现在要你选出尽可能少的几条路径,使得只要把你选出来的路径都走了一遍,就可以保证你已经走过的图中的每一个节点。注意,路径与路径之间,可以有公共点(即允许路径相交)。

思路

典型的“最小路径覆盖”问题。在这里直接给出此类问题的解法:

有向无环图最小不相交路径覆盖

       定义:用最少的不相交路径覆盖所有顶点。

       定理:把原图中的每个点V拆成Vx和Vy,如果有一条有向边A->B,那么就加边Ax-By。这样就得到了一个二分图,最小路径覆盖=原图的节点数-新图最大匹配。

       简单证明:一开始每个点都独立的为一条路径,总共有n条不相交路径。我们每次在二分图里加一条边就相当于把两条路径合成了一条路径,因为路径之间不能有公共点,所以加的边之间也不能有公共点,这就是匹配的定义。所以有:最小路径覆盖=原图的节点数-新图最大匹配。

 

有向无环图最小可相交路径覆盖

       定义:用最小的可相交路径覆盖所有顶点。

       算法:先用floyd求出原图的传递闭包,即如果a到b有路,那么就加边a->b。然后就转化成了最小不相交路径覆盖问题。

 

所谓传递闭包(Transitive Closure)就是指把原图里面所有能直接间接联通的点之间都给连上边(如果有联通的方向限制,这个方向也要保留)之后形成的图,也就是说只要在传递闭包中存在A->B,就一定可以在原图中找到一条从A到B的路径。求传递闭包使用Warshall算法,最简单的实现就是借助邻接矩阵了(下图直接截自离散数学课件):

QQ20150829-1@2x

代码

以下实现使用了Hopcraft-Karp算法和Warshall算法。

 

Leave a Reply

Scroll to top