好神奇啊!将n*n的矩阵的每行和每列分别看成一个点,而坐标就作为两个点的连线,这样的话这个题就转换为最少几个点能够覆盖到所有的边,神奇吧!
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define M 510
#define N 510
bool used[N];
int link[N];
int g[M][N];
int gm,gn;
bool find(int v)
{
int i;
for(i=1;i<=gm;i++)
{
if(!used[i]&&g[v][i]==1)
{
used[i]=true;
if(link[i]==0||find(link[i]))
{
link[i]=v;
return true;
}
}
}
return false;
}
int MaxMatch()
{
int i,ans=0;
for(i=1;i<=gm;i++)
{
memset(used,0,sizeof(used));
if(find(i)) ans++;
}
return ans;
}
int main()
{
int a,b,i;
while(scanf("%d%d",&gm,&gn)!=EOF)
{
memset(g,0,sizeof(g));
memset(link,0,sizeof(link));
for(i=1;i<=gn;i++)
{
scanf("%d%d",&a,&b);
g[a][b]=1;
}
printf("%d\n",MaxMatch());
}
return 0;
}