我发现…建二分图真的是门艺术。。这道题能想到用二分图真是太厉害了Orz
附上大佬博客:https://blog.csdn.net/zyy173533832/article/details/12654539
https://blog.csdn.net/lezg_bkbj/article/details/12260431
然后记得结果除2。。附上AC代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=605;
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[MAXN][MAXN];
int id[MAXN][MAXN];
int t;
scanf("%d",&t);
for(int tt=1;tt<=t;tt++)
{
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%s",s[i]);
int tol=0;
memset(id,-1,sizeof(id));
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(s[i][j]=='#')
{
id[i][j]=tol++;
}
memset(g,0,sizeof(g));
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
if(s[i][j]=='.')
continue;
if(i+1<n&&s[i+1][j]=='#')
g[id[i][j]][id[i+1][j]]=1;
if(j+1<n&&s[i][j+1]=='#')
g[id[i][j]][id[i][j+1]]=1;
if(i>0&&s[i-1][j]=='#')
g[id[i][j]][id[i-1][j]]=1;
if(j>0&&s[i][j-1]=='#')
g[id[i][j]][id[i][j-1]]=1;
}
int ans=0;
n1=n2=tol;
memset(link,-1,sizeof(link));
for(int u=0;u<n1;u++)
{
memset(vis,0,sizeof(vis));
if(dfs(u))
ans++;
}
printf("Case %d: %d\n",tt,ans/2);//结果除2
}
return 0;
}