二分图最大匹配简要整理

 部分内容引自xht37的博客



图的匹配

对于无向图$G=(V,E),M\subseteq L$,若$M$中任意两条边没有公共点,则称该边集$M$为图$G$的一个匹配

定义匹配的大小为边的数量$|M|$,其中边数最大的$M$为最大匹配

无法再增加匹配边的匹配为极大匹配

显然极大匹配不一定是最大匹配,但最大匹配一定是极大匹配

匹配$M$中的边称为M-匹配边,未匹配的边称为M-未匹配边

一个点如果为$M$中匹配边的端点则称为M-匹配点(M-饱和点),否则称为M-未匹配点(M-未饱和点)

若图$G$中每个结点都是M-匹配点则称$M$为完美匹配(完全匹配)

完美匹配是最大匹配,但最大匹配不一定是完美匹配

若图中节点个数为奇数且刚好只有一点是M-未匹配点则称$M$为近完美匹配

增广路

对于匹配$M$,由匹配边和非匹配边交替构成的路径称为M-交错路

显然交错路一定为简单路

M-交错回路:满足回路和交错路条件的路径

若M-交错路的始点和终点都是M-未匹配点则称该交错路为M-增广路

性质:

1,图$G$的匹配$M$为最大匹配,当且仅当$G$中不含M-增广路

2,如果把路径上所有边的状态(是否为匹配边)取反,那么得到的新的边集 仍然是一组匹配,并且匹配的边数增加了1

二分图

二分图:节点由两个集合组成,且两个集合内部没有边的图

性质:不含奇环

完备匹配:$|M|=min\{|V1|,|V2|\},V1,V2$为二分图两点集

完备匹配是最大匹配,但最大匹配不一定是完备匹配

Hall定理

判定二分图存在完备匹配的充要条件:当且仅当任取$V1$一子集$S$,有$|N(S)>=S|$,$N(S)$表示与$S$中各结点相邻的所有节点的集合

匈牙利算法

思想:

不断寻找增广路,并把增广路上所有边的状态取反,得到一个更大的匹配,直到图中不存在增广路

过程:

依次尝试给每一个左部点$x$寻找一个匹配的右部点$y$

$y$与$x$匹配需满足下面两个条件之一:

1,$y$是非匹配点。

2,$y$已与$i$匹配,但从$i$出发能找到另一个$j$与之匹配

时间复杂度$O(nm)$

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1010;
struct edge{
    int next,to;
}e[maxn*maxn];
int n,m,ed,head[maxn],cnt,ans,pre[maxn];
bool vis[maxn];
void add(int x,int y)
{
    e[++cnt].next=head[x];
    e[cnt].to=y;
    head[x]=cnt;
}
bool dfs(int x)
{
    for(int v,i=head[x];i;i=e[i].next)
        if(!vis[v=e[i].to])
        {
            vis[v]=1;
            if(!pre[v]||dfs(pre[v]))
            {
                pre[v]=x;
                return 1;
            }
        }
    return 0;
}
int main()
{
    scanf("%d%d%d",&n,&m,&ed);
    for(int x,y,i=1;i<=ed;i++)
    {
        scanf("%d%d",&x,&y);
        add(x,y);
    }
    for(int i=1;i<=n;i++)
    {
        memset(vis,0,sizeof(vis));
        if(dfs(i))
            ans++;
    }
    printf("%d\n",ans);
    return 0;
}


二分图多重匹配

定义:从二分图中选出尽量多的边,使任取点$v$满足$v$作为最多$a_v$条选出的边的端点,则称选出的边集为二分图的多重匹配

解法:拆点进行二分图最大匹配(将点$v$拆成$a_v$个点)

二分图最小点覆盖

图的点覆盖:对于一张无向图$(V,E)$,若存在一个点集$V'$,满足$V'⊆V$,且对于任意$e∈E$,$e$至少有一个端点属于$V'$,则称$V'$为这张无向图的一组点覆盖

二分图最小点覆盖:在二分图中,包含点数最少的一组点覆盖被称为二分图的最小点覆盖

定理:二分图最小点覆盖包含的点数,等于最大匹配包含的边数

二分图最大独立集

图的独立集:对于一张无向图$(V,E)$,若存在一个点集$V'$,满足$V'⊆V$,且对于任意$p,q∈V'$,$(p,q)∉E$,则称$V'$为这张无向图的一组独立集,包含点数最多的独立集被称为图的最大独立集

定理:二分图最大独立集包含的点数,等于$n-$最大匹配包含的边数

有向无环图的最小路径点覆盖

给定一张有向无环图,用尽量少的不相交的简单路径覆盖所有点(也就是每个点恰好被覆盖一次),这样的路径集合被称为最小路径点覆盖

拆点二分图

把每个点拆成编号为$x$和$x+n$的两个点

建立一张新的二分图,$1∼n$是左部点,$n+1∼2n$是右部点。

对原图的每条有向边$(x,y)$,在二分图的左部点$x$与右部点$y+n$之间连边

最终得到的二分图成为原图的拆点二分图

定理:有向无环图的最小路径点覆盖包含的路径条数,等于$n-$拆点二分图的最大匹配边数

证明:在最小路径点覆盖的方案中,因为所有路径不相交,所以每一个点的入度和出度都不超过1;因为每个节点都被覆盖,所以x的出度和入度至少有一个是1。因此,最小路径点覆盖中的所有边,在拆点二分图中构成一组匹配。最小路径覆盖中每条边(x,y)的起点x与二分图每条匹配边(x,y+n)的左部点x是一一对应的。特别地,对于每条路径的终点t,因为t没有出边,所以出度为0,对应在二分图中就是t匹配失败。即路径的终点和二分图左部的非匹配点是一一对应的。故而,G的最小路径点覆盖等于n减去最大匹配数。

可重复最小路径点覆盖

对原图进行传递闭包,按照普通最小路径点覆盖处理即可

posted @ 2021-03-31 11:27  Ivanovcraft  阅读(655)  评论(0编辑  收藏  举报