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|).

  • 相关阅读:
    事后诸葛亮
    团队作业6--展示博客(Alpha版本)
    团队作业5——测试与发布(Alpha版本)
    团队作业2:需求分析&原型设计
    团队编程作业1-团队展示与选题
    结对编程1
    TeamViewer app案例分析
    第一次作业--四则运算
    【Alpha】Daily Scrum Meeting 集合贴
    【Alpha】Daily Scrum Meeting——Day3
  • 原文地址:https://www.cnblogs.com/dilthey/p/7647630.html
Copyright © 2011-2022 走看看