📜  门| GATE CS Mock 2018 |问题 9(1)

📅  最后修改于: 2023-12-03 15:12:38.300000             🧑  作者: Mango

门| GATE CS Mock 2018 |问题 9

这是一道关于图论的问题,涉及到最小生成树和最小路径覆盖。

问题描述

给定一个有向无环图 G=(V,E),每个边都有一个非负整数的权值。定义路径 p 的权值为 p 中边的权值之和。定义路径集合 P 的权值为 P 中所有路径的权值之和。路径 p1 能够覆盖路径 p2,当且仅当 p1 从起点到终点的节点集合包含了 p2 从起点到终点的节点集合。路径集合 P 的路径覆盖是指路径集合 P 中的路径两两不相交且完全覆盖图 G

我们需要实现以下函数:

def min_weight_path_cover(G):
    pass

其中:

  • G:一个有向无环图,节点数量不超过 1000,边的数量不超过 100000
  • 函数需要返回一个元组 (w, P),其中 w 是最小路径覆盖的权值,P 是构成最小路径覆盖的路径集合。P 中的路径应该按照从起点到终点的节点序列升序排列。
示例
示例1
G = {
    (1, 2): 1,
    (1, 3): 2,
    (2, 3): 1,
    (2, 4): 2,
    (3, 5): 4,
    (4, 5): 2
}

min_weight_path_cover(G)

输出:

(5, [(1, 2), (2, 4), (3, 5)])

最小路径覆盖是 1→22→43→5

示例2
G = {
    (1, 2): 100,
    (2, 3): 200,
    (3, 4): 100,
    (4, 1): 50,
    (2, 4): 150
}

min_weight_path_cover(G)

输出:

(250, [(1, 2, 4), (3, 4)])

最小路径覆盖是 1→2→43→4

解题思路

这是一道图论题目。我们可以首先将图中所有边的方向取反,得到一张有向无环图。由于这是一张 DAG,因此可以使用拓扑排序的办法,将每个节点标上一个序号 $i$,使得边 $(i,j) \in E$ 的条件是 $i < j$。

接下来我们可以将 DAG $G=(V,E)$ 转化为一个关于点集 $V$ 的无向图 $G'=(V,E')$。在 $G'$ 中,对于每对 $i<j$,当且仅当在 DAG $G$ 中存在从 $i$ 到 $j$ 的路径时,$G'$ 中有边 $(i,j)$ 和 $(j,i)$。对于每个连通块来说,最小路径覆盖等价于最小链覆盖,可以使用二分图最大匹配算法来求解。

具体而言,我们可以将每个节点 $v \in V$ 分为两个节点 $u_v$ 和 $v'$,构造二分图 $H=(U,V',E'')$,其中 $U = {u_v \mid v\in V}$,$E''$ 包含以下三种类型的边:

  • 对于每个节点 $v\in V$,在 $H$ 中存在边 $(u_v,v')$。
  • 对于任意一条边 $(i,j) \in E$,在 $H$ 中存在边 $(u_i, v_j)$。
  • 对于任意一条边 $(i,j) \in E$,在 $H$ 中存在边 $(u_j, v_i)$。

可以证明,一个路径集合 $P$ 是 $G$ 的一组路径覆盖,当且仅当对于 $H$ 的一个匹配 $M$,对于每一条 $(u_i,v_j) \in M$,都有 $(i,j) \in P$。

于是问题就转化为在 $H$ 中求最大匹配。通过 Konig 定理,最大匹配的大小等于最小点覆盖的大小。进一步地,根据路径覆盖和链覆盖的等价性,最小链覆盖等于节点数减去最小点覆盖。

注意到 $H$ 中存在多条平行边,为了方便起见,可以将 $H$ 中的每条边的权值设置为 $0$ 或者 $1$,表示该边至多能够贡献 $1$ 的匹配度。最大匹配的大小就是最小链覆盖和最小点覆盖的大小之和。

具体算法实现可以使用 Hopcroft-Karp 算法或者 Dinic 算法进行。

参考文献:

  • CLRS 3rd Edition, Chapter 22.2.
  • GeeksforGeeks: Path Cover Problem
  • GeeksforGeeks: Maximum Bipartite Matching