二分图最大匹配问题

洛谷P3386二分图最大匹配 || 匈牙利算法

给定一张二分图,其左部点集大小为 n,右部点集大小为 m,共k条边,请求出其最大匹配。

需要注意的是,在一轮递归中,每个右部点只能被访问一次

#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e4 + 7;
const int N = 555;
typedef long long ll;

int head[maxn], vis[N], match[N], cnt;
struct edge
{
    int to, next;
}e[maxn];

void add(int u, int v)
{
    e[++cnt].next = head[u];
    e[cnt].to = v;
    head[u] = cnt;
}

bool dfs(int x)
{
    for(int i = head[x]; i; i = e[i].next)
    {
        int v = e[i].to;
        if(!vis[v])
        {
            vis[v] = 1; //这里就置为1,而不是在if里再置,因为if若成功进入,表示可以将x和v匹配,所以必须要求在整个递归过程中v都不再被选择   
            if(!match[v] || dfs(match[v]))
            {
                match[v] = x;
                return 1;
            }
        }
    }
    return 0;
}

int main()
{
    int n, m, k, x, y, ans = 0;
    scanf("%d %d %d", &n, &m, &k);
    for(int i = 1; i <= k; ++i)
    {
        scanf("%d %d", &x, &y);
        add(x, y);
    }
    for(int i = 1; i <= n; ++i)
    {
        memset(vis, 0, sizeof(vis));
        ans += dfs(i);
    }
    cout << ans << endl;
}
原文地址:https://www.cnblogs.com/Maxx-el/p/14092485.html