poj 3715 最小覆盖集,并且输出字典序最小解

  1. 首先最小覆盖集可以用二分图匹配求出来记为ans。

然后是怎么来求最小覆盖集。

 

首先枚举每个已经匹配了的点,如果去掉这个点以及和这个点所相连的所有边, 如果剩下图的二分图的最大匹匹配如果是ans-1,那么这个点就是最小覆盖集中的点,如果最大匹配还是ans,那么这个点就不是最小覆盖集点,因为如果选这个点,那么新加入的那个点肯定是在去掉的这个点一边,但是他是不能被去掉的这个点所覆盖。

 

接下来是怎么求解最小字典序,从0到n-1 ,如果找到一个点是覆盖点,那么就把他加入最小覆盖点集中,并去掉和这个点所连的所有边。

 

其实这道题并不用每次都找匹配点,因为,我们去掉一个点的话,那么用原来和他匹配的点找增广路,那么如果找到新的增广路,而原来的 点不便,那么最大匹配还是ans-1 ,所以这样的话可以极大的节约时间。

 

 

 可以看看这边文章http://blog.csdn.net/mofixroot/archive/2009/10/20/4706113.aspx

 

别人给我的思路

 

首先构图跑SAP(匈牙利应该也行,但我对匈牙利的实现细节不了解(我从未实现过匈牙利),所以不敢妄加说明)求出最小点覆盖的数量……这个没问题吧……
然后把匹配边、哪些端点被匹配了也都搞出来……这个也没问题吧……
然后我们就能发现,在每条匹配边中,有且仅有一个端点会被入选到最终结果中。
我们不妨思考一下,一个端点可以进入最终结果的条件是什么?可以发现,如果这个点是被匹配点,且删掉这个点和与其相连的所有边后的新图最小点覆盖数目比当前的数目小1,那么这个点是有资格作为最小覆盖中的点的,否则一定不能。
接下来的事情就是字典序的问题了。我们不妨从1~n枚举点,如果这个点有资格进入最小点覆盖集,就让他进入,然后删掉这个点以及和它相连的所有边。继续这个过程,显然最后得到的就是字典序最小的点覆盖集了。
事 实上,真正实现时大可不必这么麻烦。在判定一个点是否可行时,直接给这条匹配边的另一个端点一个单位流量,然后判定可否增广(虚拟的增广,一个dfs即 可)。如果可以增广,这个点就不能进入最小点覆盖集,收回刚才给的流量,否则这个点进入最终答案,那个流量不必收回,因为这时另一个匹配点还是可以被其他 点匹配的。
时间复杂度:匹配的复杂度:O(sqrt(n)*m),得出最终答案的复杂度:O(n*m),总:O(nm)
具体见代码。

 

 

2011-04-2120:22:25

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值