poj 3041 二分图最小点覆盖=二分图最大匹配
构图:把行作为x集合,把列当作y集合,如果某个位置有障碍,相应的x和y连边
每一条边对应一个障碍。问题转化为选择最小的点覆盖全部的边。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 505;
int uN, vN;
bool g[MAXN][MAXN];
int xM[MAXN], yM[MAXN];
bool chk[MAXN];
bool searchPath(int u)
{
int v;
for(v = 0; v < vN; v++)
if(g[u][v] && !chk[v])
{
chk[v] = true;
if(yM[v] == -1 || searchPath(yM[v]))
{
yM[v] = u;
xM[u] = v;
return true;
}
}
return false;
}
int maxMatch()
{
int u, ret = 0;
memset(xM, -1, sizeof(xM));
memset(yM, -1, sizeof(yM));
for(u = 0; u < uN; u++)
if(xM[u] == -1)
{
memset(chk, false, sizeof(chk));
if(searchPath(u))ret++;
}
return ret;
}
int main()
{
int n,k, a, b;
while( scanf("%d%d", &n, &k)!= EOF)
{
memset(g, 0, sizeof(g));
uN=vN =n;
while(k--)
{
scanf("%d%d",&a, &b);
a--;
b--;
g[a][b] = 1;
}
printf("%d\n", maxMatch());
}
// system("pause");
return 0;
}