二分图学习笔记

这篇博客介绍了二分图的概念,包括如何通过黑白染色法进行判定。重点讲述了二分图的最大匹配和增广路的概念,指出增广路的性质以及其在最大匹配中的作用。还详细解析了匈牙利算法,这是一种用于寻找二分图最大匹配的高效方法,通过不断寻找并反转增广路来增加匹配边的数量,直至无法找到增广路为止。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

二分图判定

使用黑白染色法,把与一个点相连的所有节点都染成与这个点不同的颜色,这样点就会被分为黑与白两个集合,如果说染色时出现了冲突,比如两个相连的点颜色均为黑色,那么黑点集中出现了边,此图便不是二分图

二分图最大匹配

任意两条边都没有公共端点的边集成为图的一组匹配,二分图中,对于包含边数最多的一组匹配称为二分图的最大匹配。匹配上的点称为匹配点,相应的有匹配边,非匹配边/点

增广路

对于一组匹配S,若二分图存在一条连接两个非匹配点的路径path,使得非匹配边与匹配边交替出现,则path就是匹配S的增广路,又称交错路

增广路具有的性质

  • 长度length为奇数
  • 路径上第1,3,5…length条边(第奇数条边)为非匹配边,第2,4,6…length-1条边为匹配边

因此我们如果把非匹配边变为匹配边,匹配边变为非匹配边,新的到的仍是一组匹配,并且匹配边数较原来的那组匹配增加了一条
进一步我们有推论,S为二分图的最大匹配,当且仅当图中不存在S的增广路(用反证法证明)

匈牙利算法(增广路算法)

求二分图最大匹配
算法过程是不断寻找增广路,每找到一次增广路,把增广路边取反,由增广路定义可知,匹配边数比原来的匹配多了一条

当一个点成为匹配点后,可能会因为寻找到了增广路,导致这个点更换匹配对象,但不可能使这个点变为非匹配点,因为增广路是匹配非匹配交错出现,取反后,对于路径两端点,他们成为匹配点,对于路径中的点,他们还是连接一条匹配边,一条非匹配边。

具体过程:首先认为图中不存在匹配边,即所有点都是非匹配点
设点X位于左部,点Y位于右部,X-Y有一条边
若Y是非匹配点,则X-Y为非匹配边,构成一条长度为1的增广路,对其取反,匹配边数加1
若Y已经和一个左部点匹配,则X-Y为非匹配边,找到Y的匹配点Z,再从Z出发去找另一个点k

  • 若k是非匹配点,找到增广路
  • 若k已经和一个左部点匹配,再找相应的匹配点,递归下去

不断重复这个过程,找到增广路后,回溯时通过改变匹配点进行取反,最后就得到二分图的最大匹配,为了避免重复搜索,还要在每次找增广路的时候开一个vis数组,搜过的点标记一下,下次访问便不再搜索,对于一次寻找增广路的过程,若从这个点出发找不到增广路,那么这个点无论一哪种方式被再次访问,依然找不到增广路

bool dfs(int x) {
    for(int i=head[x]; i; i=e[i].nxt) {
        int y = e[i].v;
        if(vis[y]) continue;
        vis[y] = 1;
        if(!match[y] || dfs(match[y])) {
            match[y] = x;//取反,匹配边是通过match来遍历的,所以通过邻接表遍历的是非匹配边
            return true;
        }
    }
    return false;
}
for(int i=1; i<=n; i++) {
    memset(vis, 0, sizeof(vis));
    if(dfs(i)) ans++;//n指左部所有节点
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值