首页 > 代码库 > [网络流专练3][最小路径覆盖问题]

[网络流专练3][最小路径覆盖问题]

题目描述

«问题描述:

给定有向图G=(V,E)。设P 是G 的一个简单路(顶点不相交)的集合。如果V 中每个顶点恰好在P 的一条路上,则称P是G 的一个路径覆盖。P 中路径可以从V 的任何一个顶点开始,长度也是任意的,特别地,可以为0。G 的最小路径覆盖是G 的所含路径条数最少的路径覆盖。设计一个有效算法求一个有向无环图G 的最小路径覆盖。提示:设V={1,2,.... ,n},构造网络G1=(V1,E1)如下:

每条边的容量均为1。求网络G1的( 0 x , 0 y )最大流。

«编程任务:

对于给定的给定有向无环图G,编程找出G的一个最小路径覆盖。

输入输出格式

输入格式:

件第1 行有2个正整数n和m。n是给定有向无环图G 的顶点数,m是G 的边数。接下来的m行,每行有2 个正整数i和j,表示一条有向边(i,j)。

输出格式:

从第1 行开始,每行输出一条路径。文件的最后一行是最少路径数。

输入输出样例

输入样例#1:
11 121 21 31 42 53 64 75 86 97 108 119 1110 11
输出样例#1:
1 4 7 10 112 5 83 6 93

Solution

1.模型:有向无环图DAG的最小路径覆盖

  • s->Xi,容量为1。
  • Xi->Yj,(i, j)∈E,容量上界为1。
  • Yi->t,容量上界为1。

DAG的最小路径覆盖=|V|-对应二分图的最大匹配。

约束是什么?对路径的定义中,有至关重要的一点:允许长度为0。于是解的存在性得到了保证。因此,只需满足:对于任意一点,至多有一条与它关联的入边和与它关联的出边被选中。
二分图的匹配,可以从顶点对应的角度看待,也可以从边的角度看待:选出一些边,使得每个顶点至多与一条边关联。和本问题的约束对比,发现有向无环图不是二分图,并且对于顶点而言,边分为入边和出边两类。考虑把点i拆成Xi、Yi,入边连到Yi,出边从Xi出发。这样,问题的约束便和二分图匹配相一致。
目标是什么?使路径覆盖数最小。除了直接数,还能用什么来刻画路径覆盖数?头的数量或尾的数量。什么样的点是头?没有匹配边与对应的Yi关联。尾?没有匹配边与对应的Xi关联。所以,DAG的最小路径覆盖=|V|-对应二分图的最大匹配。

hzwer这儿有另一种更简洁的看待方法:

如果无匹配,显然要n条路径才能覆盖所有点,两个点匹配意味着将可以把它们用一条路径覆盖,路径数就可以减1

我还有一种另类看待方法:
带上下界的网络流。
Step 1
- s->Xi,容量上界为1。
- Xi->Yi,容量下界为1,上界inf。
- Yi->Xj,(i, j)∈E,容量上界为1。
- Yi->t,容量上界为1。
求解s-t最小流。

Step 2
看出一个可行流,于是省去通常求解s-t可行流的步骤。
网络变换为:
- Xi->s,容量上界为1。
- Yi->Xj,(i, j)∈E,容量上界为1。
- t->Yi,容量上界为1。
此网络的t-s最大流与原s-t可行流的叠加,即为原s-t最小流。s-t可行流的值为|V|,用|V|去减t-s最大流即可。

这种看待方法和hzwer的在实质上相同,但是是从形式上的变换得到的。

为什么强调DAG?因为我们只是简单地拆点、匹配,而没有在意这两点是否已经在同一条路径里了。比如,一个环,对应二分图的最大匹配为|V|,实际上,作为一条有始有终的“路径”,它是不能封口的。

转载自http://blog.csdn.net/ruoruo_cheng

因此,ans=n-最大匹配

2.算法

二分图最大匹配用网络流最大流实现

[网络流专练3][最小路径覆盖问题]