二分图匹配之匈牙利算法

二分图的基本概念:

二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。

比如:

我们一般把图的两部分称为X部和Y部,一个图的所有点如果能被两个独立的点集,那就认为这个图是二分图

二分图的判断一般通过染色的方法来进行判段,可以写成dfs或则bfs的写法

bool dfs(int v,int c)
{
    color[v]=c;
    for(int i=0;i<n;i++)
    {
        if(edge[v][i]==1)
        {
            if(color[i]==c) return false;
            if(color[i]==0&&!dfs(i,-c)) return false;
        }
    }
    return true;
}
void solve()
{
    int flag=0;
    for(int i=0;i<n;i++)
    {
        if(color[i]==0)
        {
            if(!dfs(i,1))
            {
                cout<<"no"<<endl;
                flag=1;
                break;
            }
        }
     } 
     if(!flag) cout<<"yes"<<endl;
} 

bfs写法

bool bfs(int s)
{
    color[s] = 1;
    queue<int> que;
    que.push(s);
    while(!que.empty())
    {
        int from = que.front();
        que.pop();
        for(int i = 1; i <= V; i++)
        {
            // 如果相邻的点没有上色就给这个点上色
            if(G[from][i] && color[i] == 0)
            {
                que.push(i);
                color[i] = -color[from];
            }
            // 如果相邻的颜色相同则返回false
            if(G[from][i] && color[i] == color[from])
                return false;
        }
    }
    // 如果所有的点都被染过色,且相邻的点颜色都不一样,返回true
    return true;
}

接下来就是介绍匹配:

一个匹配是一个边的集合,任何匹配的边之间没有公共顶点。

最大匹配:一个图的所有匹配中,边数最多的匹配称为最大匹配。如果所有定点都是匹配顶点,则称这个匹配为完美匹配。

我们一般通过匈牙利算法来求一个二分图的最大匹配,其算法的核心是求增广路径。

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

增广路:从一个未匹配点出发,走交替路,如果途径另一个未匹配点(出发的点不算),则这条交替路称为增广路(agumenting path)。

我们每次找到一个增广路,所得到的匹配的边数都会增加一条,因此我们可以通过求所有点的增广路径来求最大匹配的边数

匈牙利算法的模板如下:

bool dfs(int x)
{
    for(int i=1;i<=p;i++)
    {
        if(!used[i]&&map[x][i]==1)
        {
            used[i]=1;
            if(!link[i]||dfs(link[i]))
            {
              link[i]=x;
              return true;
            }
        }
    }
    return false;
}
void xyl()
{
    for(int i=1;i<=n;i++)
    {
        memset(used,0,sizeof(used));
        if(dfs(i)) counts++;
    }
}

PS.练习题:hdu 1045,hdu 2444,hdu 1083

此外还有二分图的最小顶点覆盖,最大独立集,最大团等知识,求的方法和匈牙利算法的差不多可以参考如下博客

https://www.cnblogs.com/jianglangcaijin/p/6035945.html

剩下的带权二分图过几天在补充

原文地址:https://www.cnblogs.com/tombraider-shadow/p/10945775.html