每一行看成一个点,设为集合A;每一列看成一点,设为集合B
把输入的点的坐标转化成集合A到集合B的点的连线,
转化成求A、B构成的二分图的最小点覆盖,最小点覆盖数 = 最大匹配数
匈牙利算法
Code:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 500 + 5;
int mp[maxn][maxn];
int vis[maxn];
int next[maxn];
int n;
int k;
bool dfs( int s )
{
for( int i = 1; i <= n; i++ )
{
if( !vis[i] && mp[s][i] != 0 )
{
vis[i] = 1;
if( next[i] == -1 || dfs( next[i] ) )
{
next[i] = s;
return true;
}
}
}
return false;
}
int main()
{
int x;
int y;
while( ~scanf( "%d%d", &n, &k ) )
{
memset( mp, 0, sizeof( mp ) );
memset( next, -1, sizeof( next ) );
for( int i = 0; i < k; i++ )
{
scanf( "%d%d", &x, &y );
mp[x][y] = 1;
}
int ans = 0;
for( int i = 1; i <= n; i++ )
{
memset( vis, 0, sizeof( vis ) );
if( dfs( i ) )
ans++;
}
printf( "%d\n", ans );
}
return 0;
}