二分匹配基础,只要将a,b找出来就好
对于每个“ *”的4个方向进行查找并且记录他们间的关系;
因为我们对a->b和b->a都进行了读取,所以要除2;
#include<stdio.h>
#include<string.h>
char str[41][11];
bool mat[400][400],usedif[400];
int h,w,link[400],num;
int dx[4]={0,0,-1,1};
int dy[4]={1,-1,0,0};
bool can(int t)
{
for(int i=0;i<w*h;i++)
if(usedif[i]==0&&mat[t][i]==1)
{
usedif[i]=1;
if(link[i]==-1||can(link[i]))
{
link[i]=t;
return true;
}
}
return false;
}
int MaxMatch()
{
int sum=0;
memset(link,-1,sizeof(link));
for(int i=0;i<h*w;i++)
{
memset(usedif,false,sizeof(usedif));
if(can(i)) sum++;
}
return sum;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
num=0;
scanf("%d%d",&h,&w);
memset(mat,false,sizeof(mat));
for(int i=0;i<h;i++) scanf("%s",str[i]);
for(int i=0;i<h;i++)
for(int j=0;j<w;j++)
if(str[i][j]=='*')
{
num++;
for(int k=0;k<4;k++)
{
int x,y;
x=i+dx[k];
y=j+dy[k];
if(x>=0&&x<h&&y>=0&&y<w&&str[x][y]=='*') mat[i*w+j][x*w+y]=true;
}
}
printf("%d\n",num-MaxMatch()/2);
}
return 0;
}