题目链接:POJ 3041 Asteroids
把每行和每列都看成点,行列自然的分成了二部分,每个点可以看成对应的行列之间连上一条边,然后就转化成了在一个二分图上用最少的点(x 或 y 集合的都行),让每条连接两个点集的边都至少和其中一个点关联。根据konig定理:二分图的最小顶点覆盖数等于最大匹配数。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAX_N = 500 + 50;
bool _map[MAX_N][MAX_N], vis[MAX_N];
int link[MAX_N], n, k;
bool dfs(int u)
{
for(int i = 1; i <= n; i++)
{
if(!vis[i] && _map[u][i])
{
vis[i] = true;
if(link[i] == -1 || dfs(link[i]))
{
link[i] = u;
return true;
}
}
}
return false;
}
int MaxMatch()
{
int num = 0;
memset(link, -1, sizeof(link));
for(int i = 1; i <= n; i++)
{
memset(vis, 0, sizeof(vis));
if(dfs(i))
num++;
}
return num;
}
int main()
{
int u, v;
scanf("%d%d", &n, &k);
for(int i = 1; i <= k; i++)
{
scanf("%d%d", &u, &v);
_map[u][v] = 1;
}
printf("%d\n", MaxMatch());
return 0;
}