题目:http://poj.org/problem?id=2226
分析:横竖联通块为节点,交叉为边,求最小覆盖,即最大匹配
代码:
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int Tmax=105,Tmax2=4005;
int r,c,data[Tmax][Tmax],last,rr,ans,s[Tmax2];
bool map[Tmax2][Tmax2],v[Tmax2];
bool dfs(int x)
{
int i;
for(i=1;i<=last;i++)
if((!v[i])&&(map[x][i]))
{
v[i]=true;
if(s[i]==0||dfs(s[i]))
{
s[i]=x;
return true;
}
}
return false;
}
int main()
{
int i,j;
//freopen("1.in","r",stdin);
//freopen("t.out","w",stdout);
scanf("%d%d",&r,&c);
for(i=1;i<=r;i++)
{
getchar();
for(j=1;j<=c;j++)
{
scanf("%c",&data[i][j]);
if(data[i][j]=='.') data[i][j]=0;
else{
if(data[i][j-1]>0) data[i][j]=data[i][j-1];
else data[i][j]=++last;
}
}
}
rr=last;
last=0;
for(i=1;i<=c;i++)
for(j=1;j<=r;j++)
if(data[j][i]>0)
{
if(data[j-1][i]==0) last++;
map[data[j][i]][last]=true;
}
for(i=1;i<=rr;i++)
{
memset(v,0,sizeof(v));
if(dfs(i)) ans++;
}
printf("%d",ans);
return 0;
}