匈牙利算法

本文深入探讨了图论中的匹配概念,包括最大匹配和完美匹配,并详细解释了交替路与增广路的定义及其在改进匹配中的应用。通过理解和运用增广路,可以有效地增加图中匹配边的数量,最终达到最大匹配。此外,文章还讨论了二分图的最小顶点覆盖和无向图的最小路径覆盖等关键主题。

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

1.最大匹配&完美匹配
在图论中,一个“匹配”(matching)是一个边的集合,其中任意两条边都没有公共顶点。
最大匹配:一个图所有匹配中,所含匹配边数最多的匹配,称为这个图的最大匹配。
完美匹配:如果一个图的某个匹配中,所有的顶点都是匹配点,那么它就是一个完美匹配。
2.交替路&增广路
交替路:从一个未匹配点出发,依次经过非匹配边、匹配边、非匹配边…形成的路径叫交替路。
增广路:从一个未匹配点出发,走交替路,如果途径另一个未匹配点(出发的点不算),则这条交替路称为增广路。
增广路的重要特点:非匹配边比匹配边多一条,因此,研究增广路的意义是改进匹配。只要把增广路中的匹配边和非匹配边的身份交换即可。由于中间的匹配节点不存在其他相连的匹配边,所以这样做不会破话匹配的性质。交换后,图中的匹配边数目+1。
我们可以通过不停地寻找增广路来增加匹配中的匹配边和匹配点,找不到增广路时,达到最大匹配。

二分图的最小顶点覆盖:在二分图中求最少的边,让每条边至少和其中的一个点关联
最小顶点覆盖=最大匹配数
DAG图(无回路有向图)的最小路径覆盖:用尽量少的不相交的简单路径覆盖图中的所有顶点
最小路径覆盖=顶点数-最大匹配数
无向图的最小路径覆盖=顶点数-最大二分匹配/2(因为无向图就是双向的一条边等于两次入图正向和反向)

#include <set>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1000 + 4;
int map[maxn][maxn];
int link[maxn], vis[maxn];
int n, m, e, ans;
bool dfs(int u) {
    for(int v = 1; v <= m; ++v) {
        if(!vis[v] && map[u][v]) {
            vis[v] = 1;
            if(!link[v] || dfs(link[v])) {
                link[v] = u;
                return true;
            }
        }
    }
    return false;
}
void xyl() {
    memset(link, 0, sizeof(link));
    for(int i = 1; i <= n; ++i) {
        memset(vis, 0, sizeof(vis));
        if(dfs(i)) ans++;
    }
}
int main()
{
    cin >> n >> m >> e;
    int u, v;
    for (int i = 0; i < e; ++i) {
        cin >> u >> v;
        map[u][v] = 1;
    }
    xyl();
    cout << ans << endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值