这道题乍一看就是DFS,但是写了半天发现写不出来QAQ…我好菜啊55555…
搜了题解发现有人用DFS,但是写的有点烦。。
据说正确的打开方式是二分图匹配,然而我怎么都想不到emmmmm…
附上大佬博客Orz:https://blog.csdn.net/rain722/article/details/72883242
https://blog.csdn.net/vsooda/article/details/7951096
就是把行、列进行缩点,然后匹配。。太强了Orz
附上AC代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=505;
int n1,n2,k;
int g[MAXN][MAXN];
int link[MAXN];
bool vis[MAXN];
bool dfs(int u)
{
for(int v=0;v<n2;v++)
if(g[u][v]&&!vis[v])
{
vis[v]=true;
if(link[v]==-1||dfs(link[v]))
{
link[v]=u;
return true;
}
}
return false;
}
int main()
{
int n;
char s[6][6];
int row[6][6],col[6][6];
while(~scanf("%d",&n))
{
if(n==0)
break;
for(int i=0;i<n;i++)
scanf("%s",s[i]);
memset(row,-1,sizeof(row));
memset(col,-1,sizeof(col));
n1=0,n2=0;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
if(s[i][j]=='.'&&row[i][j]==-1)
{
int k=j;
while(s[i][k]=='.')//横向缩点
row[i][k]=n1,k++;//给相同的区域标记同一个数字
n1++;
}
if(s[i][j]=='.'&&col[i][j]==-1)
{
int k=i;
while(s[k][j]=='.')//纵向缩点
col[k][j]=n2,k++;//给相同的区域标记同一个数字
n2++;
}
}
memset(g,0,sizeof(g));
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(s[i][j]=='.')
g[row[i][j]][col[i][j]]=1;
int ans=0;
memset(link,-1,sizeof(link));
for(int u=0;u<n1;u++)
{
memset(vis,0,sizeof(vis));
if(dfs(u))
ans++;
}
printf("%d\n",ans);
}
return 0;
}