二分图最大匹配

匈牙利算法是要在给出一个匹配的基础上对每个非饱和点进行判断,看能否找到增广路,这边以空集为最初的集合,对每个点进行访问,寻找增广路,然后因为增广路的定义可以知道,只要找到一条增广路,肯定可以增加一条匹配边。

(增广路定义:一般是从非饱和点开始走非匹配边再匹配边,直到找到另一个非饱和点为止,(如果找不到匹配边,找一条非匹配边以非饱和点结尾的也行))

找到一条增广路,就把这个增广路的边集和原来的匹配集做异或操作(原来相同的边去掉,不同的边加入到集合中)

可以写一个find函数看能不能找到增广路,st数组是为了防止搜到同一个点出现死循环

function<bool(int)> find = [&](int u)
{
    for (const auto &i : g[u])
    {
        if (!st[i]) // 如果没走过
        {
            st[i] = 1;
            if (!match[i] || find(match[i]))
            {
                // 如果这个点没匹配或者可以找到一条增广路
                match[i] = u;
                return true;
            }
        }
    }
    return false;
};

 match[i]表示第二个集合中的点i匹配的点是match[i]这个点

容易发现一个特点,只需要存一个方向的边就行了,所以从第一个点开始每个点都是非饱和点,就可以开始找增广路。

模板题:【模板】二分图最大匹配 - 洛谷

补充个结论:最大匹配数=最小点覆盖数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值