二分图。对于每个点,将他的 x 与 y 连一条边,求最小点覆盖
二分图最小点覆盖等于最大匹配
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int n, k, hea[505], cnt, lnk[1005], ans, uu, vv;
bool vis[1005];
struct Edge{
int too, nxt;
}edge[10005];
void add_edge(int fro, int too){
edge[++cnt].nxt = hea[fro];
edge[cnt].too = too;
hea[fro] = cnt;
}
bool dfs(int x){
for(int i=hea[x]; i; i=edge[i].nxt){
int t=edge[i].too;
if(!vis[t]){
vis[t] = true;
if(!lnk[t] || dfs(lnk[t])){
lnk[t] = x;
return true;
}
}
}
return false;
}
int main(){
cin>>n>>k;
while(k--){
scanf("%d %d", &uu, &vv);
add_edge(uu, vv+n);
}
for(int i=1; i<=n; i++){
memset(vis, 0, sizeof(vis));
if(dfs(i)) ans++;
}
cout<<ans<<endl;
return 0;
}