匈牙利算法-二分图的最大匹配
in Algorithm Pageviews
给定一个二分图,其中左半部包含 n1 个顶点(编号1~n1),右半部分包含n2个顶点,二分图共包含 m 条边。数据保证任意一条边的两个端点都不会在同一部分中。
请求出该二分图的最大匹配数。
给定一个二分图 G,在 G 的一个子图 M 中,M的边集 {E} 中的任意两边都不附属于同一个顶点,则称M是一个匹配。
所有匹配中包含边数最多的一组匹配被称为二分图的最大匹配,其边数即为最大匹配数。
输入格式
第一行包含两个整数 n1 n2和 m。
接下来有 m 行,每行包含两个整数 u 和 v,表示左半部点集中的点 u 和 右半部点集中的点 v 之间存在的一条边。
输出格式
输出一个整数,表示二分图的最大匹配数。
数据范围
1 < n1,n2 <= 500,
1 <= u <= n1,
1 <= v <= n2,
1 <= m <= 105
输入样例
#include <bits/stdc++.h>
using namespace std;
constexpr int N = 510;
constexpr int M = 100010;
int idx = 0;
int e[M];
int ne[M];
bool match[N];
int h[N];
bool st[N];
void add(int a, int b)
{
e[idx] = b;
ne[idx] = h[a];
h[a] = idx++;
}
bool find(int x)
{
for (int i = h[x]; i != -1; i = ne[i]) {
int j = e[i];
if (!st[j]) {
st[j] = true;
if (match[j] == 0 || find(match[j])) {
match[j] = x;
return true;
}
}
}
return false;
}
int main()
{
int n1 = 0;
int n2 = 0;
int m = 0;
cin >> n1 >> n2 >> m;
memset(h, -1, sizeof h);
for (int i = 0; i < m; i++) {
int a = 0;
int b = 0;
cin >> a >> b;
add(a, b);
}
int res = 0;
for (int i = 1; i <= n1; i++) {
memset(st, false, sizeof st);
if (find(i)) {
res++;
}
}
cout << res;
return 0;
}