zoukankan      html  css  js  c++  java
  • 二分图匹配

      今天上算法课的时候老师讲了图的匹配问题,想起来自己以前做ACM的时候学的二分图匹配,之前没有写博客的习惯,现在太忙,好多东西容易忘,还是记录下来比较好。

      求二分图的最大匹配有两种方法,一种是构造一个“超级源点”,一个“超级汇点”,求最大流。还有一种就是匈牙利算法,其实匈牙利算法的本质也是找增广路,两种方法实际上是等价的。

      那么,增广路是如何定义的呢?首先,增广路有奇数条边,例如A->B->C->D->E->F,那么A->B,C->D,E->F是未匹配边;B->C,D->E为匹配边。也就是说一条增广路上有奇数条未匹配边和偶数条匹配边。为什么叫它增光路呢,大家想想,在这条增广路上,我们将匹配边和非匹配边互换,这样会使的匹配边的数量+1(如下图所示)。好了,那么求最大匹配的问题就变成了找增广路的问题,dfs搜索即可。

    知道了算法的主导思想之后,实现起来就非常容易了,找到一条增广路,res++即可。

     1 bool dfs(int v){
     2     used[v] = true;
     3 
     4     for(int i = 0; i < G[v].size(); ++i){
     5         int u = G[v][i], w = match[u];
     6         //如果u是未匹配的节点,或者存在与u节点匹配的点w起始的增广路
     7         //怎我们找到了一条从v起始的增广路
     8         if(w < 0 || !used[w] && dfs(w)){
     9             match[v] = u;
    10             match[u] = v;
    11             return true;
    12         }
    13     }
    14 
    15     return false;
    16 }
    17 
    18 int bipartite_matching(){
    19     int res = 0;
    20     memset(match, -1, sizeof(match));
    21 
    22     //遍历所有节点,搜索增广路
    23     for(int v = 0; v < V; ++v){
    24         if(match[v] < 0){
    25             memset(used, 0, sizeof(used));
    26             //如果dfs返回true,说明搜索到 一条增广路,res++
    27             if(dfs(v)){
    28                 res++;
    29             }
    30         }
    31     }
    32 
    33     return res;
    34 }
    View Code

    ====================================================================================

    另一个值得关注的问题就是最小覆盖覆盖问题,学竞赛的同学们都知道一个重要的结论,那就是在二分图中,|最小顶点覆盖|=|最大匹配|。

    为什么呢?

    证明:

    首先,比如我们找到了一个最大匹配,对于每一条匹配e的两个匹配点x和y。x和y中最多只有一个点连着费匹配边,否则(如下图所示),b->y->x->a就是一条增广路了,与图中不含增广路相矛盾。现在我们明白,对于每一条边,如果该边只有一端连着匹配点,则选择这个匹配点,如果两边都连着匹配点,则任意选一个点即可。但可能有人会想,会不会出现这种情况?(如下图所示),x连着非匹配点,所以我们必须选x,B连着非匹配边我们必须选择B,那么就没有点覆盖A-y了,我们仔细观察发现,显然不可能,因为图中这种情况就是一条增广路。

    好了,我们用这种方法找到了一个覆盖点的可行解,那么怎么保证最小呢?很明显,这样选是最小的,因为我希望用更少的点去覆盖是不可能的,因为覆盖这几条匹配边就至少需要这么多点才能完成。

  • 相关阅读:
    maven系列--eclipse的m2插件
    eclipse安装反编译插件
    maven系列--settings.xml
    maven系列--maven常用命令
    maven系列--maven目录
    centos 常用命令
    iis7.0 发生未知 FastCGI错误,错误代码 0x8007010b 的解决办法
    git 提交的步骤
    关于PHP函数传参的注意点
    关于SQL查询语句中的LIKE模糊查询的解释
  • 原文地址:https://www.cnblogs.com/zhazhalovecoding/p/6067202.html
Copyright © 2011-2022 走看看