/*
在2016年,佳缘姐姐喜欢上了一款游戏,叫做泡泡堂。简单的说,这个游戏就是在一张地图上放上若干个炸弹,看是否能炸到对手,或者躲开对手的炸弹。在玩游戏的过程中,小H想到了这样一个问题:当给定一张地图,在这张地图上最多能放上多少个炸弹能使得任意两个炸弹之间不会互相炸到。炸弹能炸到的范围是该炸弹所在的一行和一列,炸弹的威力可以穿透软石头,但是不能穿透硬石头。给定一张n*m的网格地图:其中*代表空地,炸弹的威力可以穿透,可以在空地上放置一枚炸弹。x代表软石头,炸弹的威力可以穿透,不能在此放置炸弹。#代表硬石头,炸弹的威力是不能穿透的,不能在此放置炸弹。例如:给出1*4的网格地图*xx*,这个地图上最多只能放置一个炸弹。给出另一个1*4的网格地图*x#*,这个地图最多能放置两个炸弹。现在小H任意给出一张n*m的网格地图,问你最多能放置多少炸弹。
*///题目背景
/*
第一行输入两个正整数n,m,n表示地图的行数,m表示地图的列数。1≤n,m≤50。接下来输入n行m列个字符,代表网格地图。*的个数不超过n*m个。
*///样例输入
类似于之前做过的一道二分图,读入map后,给图染色,横向不间断的***或x*x只要不出现#,就一直附成一个值,然后再纵向染色,同横向,然后就是建图了,首先,因为x也染了色,但是却不能放炸弹,所以需要判断是不是*,是的话,就把该点的横向颜色与纵向颜色连一条边,然后跑最大匹配。
代码
//By AcerMo
#include<cmath>
#include<cstdio>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
const int M=1050;
int n,m;
int t=0,ti=0;
char mmp[150][150];
int mat[M*5],vis[M*5];
int hcol[M][M],zcol[M][M];
int to[M*20],nxt[M*20],head[M*20],cnt;
inline void add(int x,int y)
{
to[++cnt]=y;nxt[cnt]=head[x];head[x]=cnt;
return ;
}
inline bool mid(int x)
{
for (int i=head[x];i;i=nxt[i])
{
if (vis[to[i]]) continue;
vis[to[i]]=1;
if (!mat[to[i]]||mid(mat[to[i]]))
return mat[to[i]]=x,1;
}
return 0;
}
inline void getpath()
{
for (int i=1;i<=n;i++)
for (int k=1;k<=m;k++)
if (mmp[i][k]=='*') add(hcol[i][k],zcol[i][k]);
return ;
}
inline void built()
{
for (int i=1;i<=m;i++) mmp[0][i]='#';
for (int i=1;i<=n;i++) mmp[i][0]='#';
for (int i=1;i<=n;i++)
for (int k=1;k<=m;k++)
{
if ((mmp[i][k]=='*'||mmp[i][k]=='x')&&(mmp[i][k-1]=='*'||mmp[i][k-1]=='x')) hcol[i][k]=ti;
else if ((mmp[i][k]=='*'||mmp[i][k]=='x')&&mmp[i][k-1]=='#') hcol[i][k]=++ti;
}
t=ti;ti++;
for (int i=1;i<=m;i++)
for (int k=1;k<=n;k++)
{
if ((mmp[k][i]=='*'||mmp[k][i]=='x')&&(mmp[k-1][i]=='x'||mmp[k-1][i]=='*')) zcol[k][i]=ti;
else if ((mmp[k][i]=='*'||mmp[k][i]=='x')&&mmp[k-1][i]=='#') zcol[k][i]=++ti;
}
getpath();
return ;
}
inline void clean()
{
memset(vis,0,sizeof(vis));
return ;
}
signed main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) scanf("%s",mmp[i]+1);
built();int ans=0;
for (int i=1;i<=t;clean(),i++)
if (mid(i)) ans++;
cout<<ans;
return 0;
}