-
Notifications
You must be signed in to change notification settings - Fork 0
/
content.json
1 lines (1 loc) · 4.84 KB
/
content.json
1
{"pages":[],"posts":[{"title":"欢迎来到我的博客!","text":"这里是ZXJ_Hans的博客,我会在这里记录_各种东西_,欢迎来看。","link":"/Welcome/"},{"title":"二分图最大匹配","text":"定义 匹配:任意两条边都没有公共端点的边的集合被称为图的一组匹配。 最大匹配:在二分图中,包含边数最多的一组匹配。 匹配边与非匹配边:对于任意一组匹配S,属于S的边被称为匹配边,不属于S的被称为非匹配边。 匹配点与非匹配点:匹配边的端点被称为匹配点,非匹配边的端点被称为非匹配点。 增广路:连结两个非匹配点的路径,使得非匹配边与匹配边交替出现。 完备匹配:给定一张二分图,其左部、右部端点数量都为N,如果该二分图的最大匹配包含N条匹配边,则称该二分图具有完备匹配。 接下来我们看几张图来帮助理解。 如图2,这是一个二分图。 如图3,所有红色的边就是该二分图的一组匹配。很显然,两条红色的边都没有公共端点。 再看图4,此时所有红色的边组成的也是一组匹配,而且是最大匹配,甚至还是完备匹配。因为匹配边的数量不能再多了,而且匹配边的数量和左右部端点数相同。 如图5,又是一张二分图,红色边的是一组匹配,红色的点就是匹配点了。 如图6,就是图5的一条增广路了,可以看到,第一个端点和最后一个端点都是非匹配点,途中经过的边是非匹配边,匹配边的方式交替的。 问题关于二分图匹配的问题,最常见的应该就是求二分图的最大匹配了吧。。。 举个例子,看这张图: 图中男女可以凑成一对的被连上了边,那我们要尽可能的促成他人的爱情,抽象出来,也就是求二分图最大匹配了。 (虽然我觉得这样的人际关系很渣,但没办法它是服务于学术的呢。。。) 为了解决这么一个渣男渣女问题,我们需要用到一个和这个问题一样让人感觉不太舒服的算法(笑。 匈牙利算法匈牙利算法,又称增广路算法,顾名思义,运用到了增广路的性质,这里就对增广路的一些性质进行补充。 增广路的性质(建议结合上面增广路的定义看) 长度为奇数,这是显然的,因为是交替的嘛。 路径上第奇数号的边是非匹配边,偶数号的是匹配边。 看到以上性质,你有没有明白些什么?? 没有,好,那就容我BB两句。有我也要BB 如果我们把增广路上的每条边状态取反,就能得到一个新匹配S’,而且比原来的匹配S大了1! 进一步我们可以得到推论: ==二分图的一组匹配S是最大匹配,当且仅当图中不存在S的增广路。== 算法流程有了以上知识,我们可以开始看匈牙利算法的过程了: 设S为空集,即所有边都是非匹配边。 寻找增广路,再把路径上所有边的匹配状态取反,得到了一个更大的匹配S’。 算法的关键在于,怎么找到一条增广路。 事实上这还是挺简单的,也没啥高深思想。就是尝试给每个左部节点去找右部节点来匹配。右部节点y能与左部节点x匹配,需要满足下列条件之一: y本身就是非匹配点。此时边(x,y)本身就是一条增广路了,长度为1。 y已经和左部节点x’匹配了,但可以从x’出发找到另一个右部节点y’与之匹配。那我们就把x’和y’连上,再连x和y。这样,x->y->x’->y’就构成了一条增广路。 程序方面,这里是用深度优先搜索实现的。递归地从x出发寻找增广路,如果找到了,就在回溯的同时对沿路的边进行取反。还要同时用全局vis数组来记录访问状态,避免重复搜索。 这里再推荐一个简单易懂的文章,不清楚的同学可以再去看看。 匈牙利算法的正确性基于贪心思想,因为一旦一个点成为了匹配点,至多因为找到增广路而更换匹配对象,不会再变回非匹配点。 代码实现bool dfs(int x) { for(int e=head[x];e;e=nxt[e]) { int y=ver[e]; if(vis[y]) continue; if(!match[y]||dfs(match[y])) //match记录匹配点 { match[y]=x; //修改匹配点,递归查找增广路 return true; } } return false; } int main() { for(int i=1;i<=n;i++) { memset(vis,0,sizeof(vis)); //每次搜完记得初始化访问状态 if(dfs(i)) ans++; } } 适用情况二分图匹配能适用的模型有两个要素: 节点能分成两个独立的集合,每个集合内部有0条边。 每个节点只能玉1条匹配边相连。 同时满足以上两个要素,就该考虑使用二分图匹配了。","link":"/efzdpp/"}],"tags":[{"name":"欢迎","slug":"欢迎","link":"/tags/欢迎/"},{"name":"图论","slug":"图论","link":"/tags/图论/"}],"categories":[{"name":"算法","slug":"算法","link":"/categories/算法/"}]}