📅  最后修改于: 2023-12-03 15:12:38.300000             🧑  作者: Mango
这是一道关于图论的问题,涉及到最小生成树和最小路径覆盖。
给定一个有向无环图 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
中的路径应该按照从起点到终点的节点序列升序排列。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→2
,2→4
,3→5
。
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→4
, 3→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''$ 包含以下三种类型的边:
可以证明,一个路径集合 $P$ 是 $G$ 的一组路径覆盖,当且仅当对于 $H$ 的一个匹配 $M$,对于每一条 $(u_i,v_j) \in M$,都有 $(i,j) \in P$。
于是问题就转化为在 $H$ 中求最大匹配。通过 Konig 定理,最大匹配的大小等于最小点覆盖的大小。进一步地,根据路径覆盖和链覆盖的等价性,最小链覆盖等于节点数减去最小点覆盖。
注意到 $H$ 中存在多条平行边,为了方便起见,可以将 $H$ 中的每条边的权值设置为 $0$ 或者 $1$,表示该边至多能够贡献 $1$ 的匹配度。最大匹配的大小就是最小链覆盖和最小点覆盖的大小之和。
具体算法实现可以使用 Hopcroft-Karp 算法或者 Dinic 算法进行。
参考文献: