洛谷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; }