[关闭]
@y20070316 2017-04-04T03:16:12.000000Z 字数 2312 阅读 1129

二分图の模型

网络流



一、参考资料

https://blog.sengxian.com/algorithms/networkflow-variants
http://www.matrix67.com/blog/archives/116
http://dsqiu.iteye.com/blog/1689505

二、匹配,边覆盖,独立集,点覆盖之间的三组关系及原理

(一)最大匹配与最小边覆盖

  对于任意连通图,有:


  用中文描述就是:

证明:
  若在边覆盖集中新增一条边,则有三种情况:
① 当边的两端都被覆盖时,多覆盖了 个点
② 当边一端覆盖一端未覆盖时,多覆盖了 个点
③ 当边的两端都未被覆盖时,多覆盖了 个点

  由于我们要用最小的边,覆盖所有的 个点,所以每次覆盖的边肯定越多越好。
  能覆盖 个点的边就是最大匹配,接下来,对于每个没有被覆盖的点,找到一条它与被覆盖的点的连边,把这条边连起来就好了。

  所以
  所以

(二)最大独立集与最小点覆盖的关系

  对于任意图,有:


  数量化之后,有

  用中文描述就是:在点集 中,最大独立集 与最小点覆盖 互补

证明:
  对于一个独立集 ,设它在 中的补集为
  根据独立集的定义, 中的节点两两不相邻,所以与 中节点相连的边对应的节点一定在补集 中。而还有一种类型的边,就是两个点都在补集 中。
  所以,对于每条边,它一定至少有一个端点在补集 中,即 是一个点覆盖集。
  所以对于任意一个独立集,有且仅有一个点覆盖集与其互补。
  所以当且仅当独立集为最大独立集时,最大独立集的补集为最小点覆盖。

(三)二分图中最大匹配与最小点覆盖的关系(König定理)

König定理:在二分图中,有


用中文描述就是,最大匹配数=最小点覆盖数

证明:
  首先提出构造方法。
  进行二分图最大匹配,对于右端所有没被匹配的点,找增广路,将点进行标记。
  最小点覆盖为左端所有被标记的点,和右端所有未被标记的点。

  为什么点的个数等于最大匹配数?这是因为,在我们选取的点集中,每个点都在一个匹配上,且每个匹配上只有一个点集上的点。即:最大匹配上的每一条边有且仅有一个点集中的点。

  为什么点集为点覆盖集?即证明:不存在一条边,左边的点为被标记,右边的点被标记。
  假设存在一条边,左边的点为被标记,右边的点被标记,分类讨论:当这条边是匹配边时,必然是从左走到右,既然左边没有被标记,那么右边也不能被标记;当这条边未被匹配时,必然是从右走到左,既然右边被标记了,那么就可以走到左边啊。所以不存在。

  为什么点覆盖集最小?
  这是因为,我们既然有了最大匹配的边数,则至少有个点,所以至少要用个点来覆盖。所以取到了下限。

  综上,有

三、二分图最大匹配

【构造方法】【计数方法】 Hungary算法

  1. #define rep(i,a,b) for (int i=(a);i<=(b);i++)
  2. int mp[N][N];
  3. int used[N],att[N];
  4. int res;
  5. int Hungary(int x) {
  6. rep(nx,1,n)
  7. if (!used[nx]&&mp[x][nx]) {
  8. used[nx]=1;
  9. if (!att[nx]||Hungary(att[nx])) {
  10. att[nx]=x;
  11. return 1;
  12. }
  13. }
  14. return 0;
  15. }
  16. void Match(void) {
  17. rep(i,1,n) {
  18. memset(used,0,sizeof used);
  19. Hungary(i);
  20. }
  21. res=0;
  22. rep(i,1,n)
  23. res+=(att[i]>0);
  24. printf("%d\n",res);
  25. }

四、二分图最小边覆盖

【计数方法】 ,只需要求二分图最大匹配即可;
【构造方法】
① 求二分图最大匹配,最大匹配的边全部都要取
② 然后对于没有被匹配的点,选取一条它与被匹配的点相连的边

五、二分图最小点覆盖

【计数方法】
【构造方法】
① 二分图最大匹配
② 对于右边所有没有被匹配的点,尝试找增广路,把遍历的点进行标记
③ 点覆盖集为:左边被标记的点+右边未被标记的点

六、二分图最大独立集

【计数方法】
【构造方法】求出最小点覆盖,取补集。

七、二分图最大团

【计数方法】
【构造方法】 补图的最大独立集

八、最小路径覆盖问题

【定义】在图 中,用最少的路径覆盖所有的点
为了方便表示,记最小路径覆盖数为

【建模】在图 中,将每个点 拆成两个点 ,构成二分图,若 ,则把 连接一条边。若要求路径不交叉,则直接连接;若路径可以交叉,则应该先用Floyd求解传递闭包。
【计数方法】


【构造方法】
  进行二分图最大匹配,若 连接了一条边,说明有 的路径。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注