建图过程 主要是行列匹配的思想行列式独立的
先按行记录每个区域的车能走的左边界和右边界把这个左边界和右边界进行编号为c
再按列记录每个区域的车能走的上边界和下边界把这两个边界之间的点编号为e
然后遍历图的大小对于每个点link[c][e] = 1;
建图完毕
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#define maxn 20
using namespace std;
char mp[maxn][maxn];
int link[maxn][maxn],used[maxn],id1[maxn][maxn],flag[maxn],id2[maxn][maxn];
int n,rCnt,cCnt;
bool dfs(int x)
{
for(int i=1;i<=cCnt;i++)
if(link[x][i]&&!used[i])
{
used[i] = true;
if(flag[i]==0||dfs(flag[i]))
{
flag[i] = x;
return true;
}
}
return false;
}
int match()
{
int ans = 0;
memset(flag,0,sizeof(flag));
for(int i=1;i<=rCnt;i++)
{
memset(used,0,sizeof(used));
ans += dfs(i);
}
return ans;
}
int main()
{
while(scanf("%d",&n)&&n)
{
rCnt = 0,cCnt = 0;
memset(link,0,sizeof(link));
memset(id1,0,sizeof(id1));
memset(id2,0,sizeof(id2));
for(int i=1;i<=n;i++)scanf("%s",mp[i]+1);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(mp[i][j]=='.')
{
if(j-1==0||mp[i][j-1]=='X') rCnt++;
id1[i][j] = rCnt;
}
for(int j=1;j<=n;j++)
for(int i=1;i<=n;i++)
if(mp[i][j]=='.')
{
if(i-1==0||mp[i-1][j]=='X')cCnt++;
id2[i][j] = cCnt;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
link[id1[i][j]][id2[i][j]] = true;
printf("%d\n",match());
}
return 0;
}