有关二分图匹配的一些算法

  今天学习了下二分图,算是进来的比较新的一块内容了吧。

  关于匈牙利算法之前也看过一些,但一直没怎么搞懂,今天看了个很好的博客,茅塞顿开啊。

  一看就懂的匈牙利算法:http://blog.csdn.net/dark_scope/article/details/8880547

  关于二分图的东西我也不是太懂(自行百度)。再说一些很专业的东西知道了也没什么用(假的),所以很多证明类的东西也不会,也就讲讲板子吧。

  最大匹配:

  匈牙利算法——这是整个二分图中最有用的算法了,也是最基本的算法。

  主要是一个增广路的过程(我乱编的)。

  每次寻找时,如果目标点还没被占用就直接连上。如果被占用了就把目标点和它之前相连的点的边先拆掉,再递归看看原来的匹配点有没有其它的目标点可供选择。

  还是建议看上面的博客(实在是讲不清楚)

  模板CODE

inline bool find(int now)
{
    for (int i=head[now];i!=-1;i=e[i].next)
    if (!vis[e[i].to])
    {
        vis[e[i].to]=1;
        if (!from[e[i].to]||find(from[e[i].to]))
        {
            from[e[i].to]=now;
            return 1;
        }
    }
    return 0;
}

  在主程序中只要(注意要清零vis数组,因为它是记录当次是否匹配成功的),最后ans就是最大匹配

for (i=1;i<=n;++i)
{   memset(vis,
0,sizeof(vis));   ans+=find(i); }

  

  关于二分图其它性质的东西(结论及证明等参考http://blog.csdn.net/flynn_curry/article/details/52966283

  概念:

  最小顶点覆盖:用最少的点,让每条边都至少和其中一个点关联;

  最小边覆盖:用尽量少的不相交简单路径覆盖有向无环图(DAG)G的所有顶点;

  最大独立集:在N个点的图G中选出m个点,使这m个点两两之间没有边的点中,m的最大值。

  结论:

  (a)、对于不存在孤立点的图,最大匹配+最小边覆盖=顶点数;
  (b)、最大独立集+最小顶点覆盖=顶点数;
  二分图中:
  (c)、最大匹配=最小顶点覆盖。

  (其实像我这样的蒟蒻只用记记结论就好了,证明可以看上面的博客,讲的很详细)

  另外有些板子题:

  Luogu 3386:二分图最大匹配的板子题;

  POJ 3041:最小顶点覆盖的板子题;

  POJ 3020:最小边覆盖的板子题;

posted @ 2018-03-10 19:40  空気力学の詩  阅读(186)  评论(1编辑  收藏  举报