题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2119
题解:把行和列看成二分图的两部分,每个1连接一个行一个列,就是二分图的边,每个边只要选一个点就能删除,选择最少的点覆盖所有的边
#include <stdio.h>
#include <string.h>
#define MAXN 102
int map[MAXN][MAXN];
int from[MAXN],used[MAXN];
//二分图的最小点覆盖数=最大匹配数
int match(int x,int m)//匈牙利算法
{
int i;
for(i=0;i<m;++i)
{
if(!used[i]&&map[x][i])
{
used[i]=1;
if(from[i]==-1||match(from[i],m))
{
from[i]=x;
return 1;
}
}
}
return 0;
}
int main()
{
int n,m,sum,i,j;
while(scanf("%d",&n)&&n)
{
sum=0;
//memset(map,0,sizeof(map));
memset(from,-1,sizeof(from));
scanf("%d",&m);
for(i=0;i<n;++i)
{
for(j=0;j<m;++j)
{
scanf("%d",&map[i][j]);
}
}
for(i=0;i<n;++i)
{
memset(used,0,sizeof(used));
if(match(i,m))
++sum;
}
printf("%d\n",sum);
}
return 0;
}