题意:
这里有一片油田,但是不是纯净的,有的地方是水,现在有一个捞石油的机器,但是这个机器捞的范围是固定的,是2*1的一个矩形大小,那么对于整个油田打捞,也只能打捞2*1的地方,那么,最多可以打捞多少?
题解:
这里对于图中每一个‘#’,我们就遍历四周有没有‘#’,如果有,那么这个’#’就可以和旁边的‘#‘就可以匹配,但是这里的图中都是字符,我们就先遍历一次,对于每个’#’编号,然后建图,这里我的处理方式是从上到下,从左到右,对于每一个’#‘,就只看右边和下边有没有’#‘,然后建双向边,实际上和对于每个点,向四个方向找’#’是一样的
简单的二分匹配,用匈牙利算法。模版题。。
代码:
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1000;
char Map[610][610];
int tt[610][610];
int uN,vN;
int g[MAXN][MAXN];
int linker[MAXN];
bool used[MAXN];
bool dfs(int u)
{
int v;
for(v=0;v<vN;v++)
{
if(g[u][v]&&!used[v])
{
used[v]=true;
if(linker[v]==-1||dfs(linker[v]))
{
linker[v]=u;
return true;
}
}
}
return false;
}
int hungary()
{
int res=0;
int u;
memset(linker,-1,sizeof(linker));
for(u=0;u<uN;u++)
{
memset(used,0,sizeof(used));
if(dfs(u)) res++;
}
return res;
}
int main()
{
int T;
int n;
scanf("%d",&T);
int iCase=0;
int tmp;
while(T--)
{
iCase++;
scanf("%d",&n);
tmp=0;
for(int i=0;i<n;i++)
{
scanf("%s",Map[i]);
for(int j=0;j<n;j++)
if(Map[i][j]=='#')
tt[i][j]=tmp++;
}
memset(g,0,sizeof(g));
uN=vN=tmp;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
if(Map[i][j]!='#') continue;
if(i>0&&Map[i-1][j]=='#') g[tt[i][j]][tt[i-1][j]]=1;
if(i<n-1&&Map[i+1][j]=='#') g[tt[i][j]][tt[i+1][j]]=1;
if(j>0&&Map[i][j-1]=='#') g[tt[i][j]][tt[i][j-1]]=1;
if(j<n-1&&Map[i][j+1]=='#') g[tt[i][j]][tt[i][j+1]]=1;
}
int res = hungary();
printf("Case %d: %d\n",iCase,res/2);
}
return 0;
}