题目来源:http://cn/showproblem.php?pid=1045
题意
在边长不超过4的方阵里,存在黑色的块和无色的块,在方阵里放置一种碉堡,能够朝向上下左右发射炮弹,那么为了使碉堡之间不能够相互攻击,最多放几个碉堡。
思路
有了这张图,一切好说:
这是样例1,能够放置碉堡的组合。
比如,如果x2和y2组合了,那么就不能和y3组合了。所以这个时候问题就转化成了二分匹配。
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char str[5][5];
int mp[100][100],pre[100],vis[100];
int x[100][100],y[100][100];
int t_x,t_y;
int solve(int i)
{
for(int j=1; j<=t_y; j++)
{
if(mp[i][j]&&!vis[j])
{
vis[j]=1;
if(pre[j]==-1||solve(pre[j]))
{
pre[j]=i;
vis[j]=0;
return 1;
}
}
}
return 0;
}
int main()
{
int n;
while(~scanf("%d",&n)&&n)
{
for(int i=1; i<=n; i++)
scanf("%s",str[i]+1);
for(int j=1; j<=n; j++)
str[j][0]='X';
for(int i=1; i<=n; i++)
str[0][i]='X';
memset(mp,0,sizeof(mp));
memset(pre,-1,sizeof(pre));
memset(vis,0,sizeof(vis));
memset(x,0,sizeof(x));
memset(y,0,sizeof(y));
t_x=0,t_y=0;
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
{
if(str[i][j]!='X')
{
if(str[i][j-1]=='X')
x[i][j]=++t_x;
else x[i][j]=x[i][j-1];
if(str[i-1][j]=='X')
y[i][j]=++t_y;
else y[i][j]=y[i-1][j];
}
}
}
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
if(str[i][j]!='X')
mp[x[i][j]][y[i][j]]=1;
int ret=0;
for(int i=1; i<=t_x; i++)
{
ret+=solve(i);
}
printf("%d\n",ret);
}
}