赤裸裸的二分匹配。。。
#include"stdio.h"
#include"string.h"
#define N 601
int map[N][N],v[N],link[N],a[N][N];
char str[N][N];
int n;
int dfs(int k)
{
int i;
for(i=0;i<n;i++)
{
if(map[k][i]&&!v[i])
{
v[i]=1;
if(link[i]==-1||dfs(link[i]))
{
link[i]=k;
return 1;
}
}
}
return 0;
}
int main()
{
int i,j,t,ans,tt,cnt;
scanf("%d",&t);
tt=0;
while(t--)
{
scanf("%d",&n);
cnt=0;
memset(a,0,sizeof(a));
for(i=0;i<n;i++)
{
scanf("%s",str[i]);
for(j=0;j<n;j++)
if(str[i][j]=='#')
a[i][j]=cnt++;
}
memset(map,0,sizeof(map));
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(str[i][j]=='#')
{
if(i>0&&str[i-1][j]=='#')
map[a[i][j]][a[i-1][j]]=1;
if(i<n-1&&str[i+1][j]=='#')
map[a[i][j]][a[i+1][j]]=1;
if(j>0&&str[i][j-1]=='#')
map[a[i][j]][a[i][j-1]]=1;
if(j<n-1&&str[i][j+1]=='#')
map[a[i][j]][a[i][j+1]]=1;
}
}
}
n=cnt;
memset(link,-1,sizeof(link));
ans=0;
for(i=0;i<n;i++)
{
memset(v,0,sizeof(v));
if(dfs(i))
ans++;
}
printf("Case %d: %d\n",++tt,ans/2);
}
return 0;
}