zoukankan      html  css  js  c++  java
  • 匈牙利算法及其模板

    引用来自https://www.renfei.org/blog/bipartite-matching.html

    二分图:把一个图G的所有顶点划分为两个不相交集 L 和 R ,使得图G中每一条边都分别连接 L , R 中的顶点。如果存在这样的划分,则此图为一个二分图。

    匹配:一个「匹配」(matching)是一个边的集合,其中的任意两条边都没有公共顶点。

    最大匹配:在一个图的所有匹配中,存在一个匹配,它所含的边的数量是所有匹配中最多的,该匹配称为这个图的最大匹配。

    交替路:从一个未匹配点出发,依次经过非匹配边、匹配边、非匹配边……形成的一条路径叫做交替路。

    增广路:对于一条交替路,其终点若为一个未匹配点(出发点不算),则这条交替路称为增广路(agumenting path)。

      (因为交替路的定义使得其,除了路径的起点和终点外,不存在未匹配点)

    增广路有一个重要特点:

      非匹配边比匹配边多一条。因此,研究增广路的意义是改进匹配,对增广路的增广:只要把增广路中的匹配边和非匹配边的身份交换即可。

      由于中间的匹配节点不存在其他相连的匹配边,所以这样做不会破坏匹配的性质。交换后,图中的匹配边数目比原来多了 1 条。

    那么根据增广路定理,找不到增广路时达到最大匹配;

    故因此得到匈牙利算法:

    从L集的第1个顶点开始,枚举未匹配点 i 进行搜索,寻找增广路。

      若走到了某个未匹配点,则代表寻找到了一条增广路,立即进行增广,匹配边数 +1;

      然后显然 i 点成为一个匹配点,根据交替路的定义所以不再有从 i 点出发的交替路,也就没有增广路,故停止以 i 点为起点的搜索,进入下一个点。

      如果一直没有找到增广路,则也不再从 i 点搜索,直接进入下一个点。

    匈牙利算法模板:

    struct Edge{
        int u,v;
    };
    vector<Edge> E;
    vector<int> G[MAX];
    int lN,rN;//二分图L,R集各自的顶点数
    int match[MAX];
    int vis[MAX];
    bool dfs(int u)
    {
        for(int i=0,_size=G[u].size();i<_size;i++)
        {
            int v=E[G[u][i]].to;
            if (!vis[v])
            {
                vis[v]=1;
                if(!matching[v] || dfs(matching[v]))//若遇到未匹配点,直接进行增广;否则继续搜索.
                {
                    matching[v]=u;
                    matching[u]=v;
                    return true;
                }
            }
        }
        return false;
    }
    int hungarian()
    {
        int ret=0;
        memset(matching,0,sizeof(matching));
        for(int i=1;i<=lN;i++)
        {
            if(!matching[i])
            {
                memset(vis,0,sizeof(vis));
                if(dfs(i)) ret++;
            }
        }
        return ret;
    } 

     复杂度O(|V|*|E|).

  • 相关阅读:
    关于Maya Viewport 2.0 API 开发的介绍视频
    春节大假
    Some tips about the life cycle of Maya thread pool
    Can I compile and run Dx11Shader for Maya 2015 on my side?
    How to get current deformed vertex positions in MoBu?
    想加入全球首届的 欧特克云加速计划吗?
    三本毕业(非科班),四次阿里巴巴面试,终拿 offer(大厂面经)
    mac、window版编辑器 webstorm 2016... 永久破解方法。
    node 搭载本地代理,处理web本地开发跨域问题
    js 一维数组,转成嵌套数组
  • 原文地址:https://www.cnblogs.com/dilthey/p/7647630.html
Copyright © 2011-2022 走看看