把行、列分别看作二分图的左、右边,若在坐标(i,j)处有一点,则左边的第 i 点与右边的第 j 点相连。此二分图的最大匹配数就是答案。
至于是什么原理,没有搞懂。。好像是关于最小覆盖什么的。最大匹配即是最小覆盖,应该有人证过。
二话不说,匈牙利算法。
#include<iostream>
#include<cstring>
#define FOR(i, N) for(int i = 1; i <= (N); i++)
using namespace std;
bool map[501][501];
bool visit[501];
int match[501];
bool dfs(int x, int N){
FOR(i, N){
if(map[x][i] && !visit[i]){
visit[i] = true;
if(match[i] == 0 || dfs(match[i], N)){
match[i] = x;
return true;
}
}
}
return false;
}
int Hungary(int N){
int result = 0;
FOR(i, N){
memset(visit, false, sizeof(visit));
if(dfs(i, N))
result++;
}
return result;
}
int main(){
int N, K;
cin >> N >> K;
memset(map, false, sizeof(map));
memset(match, 0, sizeof(match));
FOR(i, K){
int x, y;
cin >> x >> y;
map[x][y] = true;
}
cout << Hungary(N) << endl;
}