二分图:对于图G=(V,E),存在一种方式,将V划分为两个点集,每个点集内任意两个点间没有边。
覆盖:V的子集,E中每条边至少有一个顶点在该集合中。
最小覆盖:能够覆盖G的最少顶点集合。
匹配:E的子集,该集合中任意两条边不相交。
最大匹配:能够匹配G的最大边集合。
定理:二分图中的最小覆盖数等于最大匹配数。
先证充分性。记二分图的最小覆盖数为m,最大匹配数为n,显然有:
m⩾\geqslant⩾n (1)\begin{pmatrix}1\end{pmatrix}(1)
因为最大匹配中的边均不相交,必须在最大匹配中每个边至少选取一个顶点才能保证覆盖这些边。
也可以像下面这样证:
将最小覆盖集内外的点分别放在两个集合,如下图中左边椭圆为最小覆盖集,其内部可能存在边,由红线表示;右边为其他点组成的集合,假如右边集合中存在边,则最小覆盖集中的点不能覆盖所有边,与事实矛盾。所以图中的边只存在于左边集合内部或者左边集合与右边集合的点之间(由黑线表示),记为边的存在性定理。假如存在一个匹配集,其中所有边的一个顶点都在最小覆盖集中,这种情况下的匹配数为m,结合上述边的存在性定理,有:
m⩾\geqslant⩾n

至于如何证明m⩽\leqslant⩽n,感觉不好证,先待定
再证必要性。首先证最大匹配集中同一条边的两个顶点不能同时与集合外面的点相连,如下图所示,其中红色边为最大匹配集中的边。在这种情况下,将图中红色边替换为黑色边,则最大匹配集中会多一条边,与事实矛盾。以上命题得证。然后证最大匹配集外的点之间肯定不相连,因为如果相连,则向最大匹配集中加入这条边,结果集合中的所有边依然不相交,与事实矛盾。所以我们对于最大匹配集中的每条边,如果存在与集合外的点相连的顶点,就将这个顶点加入覆盖集,如果没有,则随便选取一个顶点加入覆盖集。这样得到的覆盖集为什么最小?因为这是从所有匹配边中选择的,如果删除一个点则对应的匹配边不能被包括在内。所以最小覆盖集=最大匹配集。

寻找最大覆盖集个数可以使用匈牙利算法,附上用哈希表示的代码:
unordered_map<int,vector<int>> mp;//边的哈希表示
unordered_map<int,int> pre,vis;
int dfs(int i){
for(auto j:mp[i]){
if(vis[j]==-1){
vis[j]=1;
if(pre[j]==-1 || dfs(pre[j])){
pre[j]=i;
return 1;
}
}
}
return 0;
}
int algorithm() {
int res=0;
for(auto edges:mp){
for(auto is_visited:vis) vis[is_visited.first]=-1;
res+=dfs(edges.first);
}
return res;
}
本文介绍了二分图的概念,包括最小覆盖和最大匹配的定义。最小覆盖是覆盖图中边的最少顶点集合,最大匹配是不相交边的最大集合。定理表明在二分图中最小覆盖数等于最大匹配数。文章通过证明充分性和必要性来解释这一定理,并提及匈牙利算法在寻找最大匹配中的应用。
3916

被折叠的 条评论
为什么被折叠?



