二分图最大匹配
匈牙利算法 \(\mathcal O(mn)\)
匈牙利算法二分图最大匹配如下图所示:

这时, 我们一个一个看
首先先匹配第一个
我们总是找对方能连上的第一个进行匹配

匹配上一个之后,再匹配第二个
...
匹配到第三个时,发生了一点小状况

可以看到,第一个和第三个撞了
这是难道要死了这条心吗 \(???\)
不,我们要向第一个发起挑战
我们要谨慎地询问1还有没有第二选择:
有,则横刀夺爱,无,则束手就擒。
匹配好的图如图所示

最大匹配数为 \(3\)
以下是代码
#include<bits/stdc++.h>using namespace std;struct Node{int to, nxt;
} ed[100010];int hd[100010], cnt;void add(int u, int v){ed[++ cnt] = {v, hd[u]};hd[u] = cnt;
}int n1, n2, m, ans;
bool has[1010];
int match[1010];int find(int u){for(int i = hd[u]; i; i = ed[i].nxt){int v = ed[i].to - n1;if(!has[v]){has[v] = 1;if(match[v] == 0 || find(match[v])){match[v] = u;return 1;}} }return 0;
}int main(){scanf("%d%d%d", &n1, &n2, &m);for(int i = 1; i <= m; i ++){int a, b;scanf("%d%d", &a, &b);add(a, b + n1);}for(int i = 1; i <= n1; i ++){memset(has, 0, sizeof has);ans += find(i);}printf("%d\n", ans);return 0;
}