您的位置:首页 > 其它

【二分匹配】hdu 4185 Oil Skimming

2014-01-03 12:14 453 查看
http://acm.hdu.edu.cn/showproblem.php?pid=4185

题意:有一个能取1*2(水平和竖直方向)油井的机器,问能最多取多少个’##‘

分析:给每一个‘#’标号,‘#’可以与周围四个‘#’匹配,建立二分图,然后直接求最大匹配

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

const int NM=605;
char str[NM][NM];
int c[NM][NM],a[NM][NM],flag[NM],link[NM],k;

int Find(int x)
{
for(int i=0;i<k;i++)
{
if(a[x][i]&&!flag[i])
{
flag[i]=1;
if(link[i]==-1||Find(link[i]))
{
link[i]=x;
return 1;
}
}
}
return 0;
}

int main()
{
int T,i,j,w,ans,n;
scanf("%d",&T);
w=1;
while(T--)
{
scanf("%d",&n);
k=1;
for(i=0;i<n;i++)
{
scanf("%s",str[i]);
for(j=0;j<n;j++)
if(str[i][j]=='#')
c[i][j]=k++;
}

memset(a,0,sizeof(a));
memset(link,-1,sizeof(link));
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
if(str[i][j]!='#') continue;
if(i>0 && str[i-1][j]=='#') a[c[i][j]][c[i-1][j]]=1;
if(i<n-1 && str[i+1][j]=='#') a[c[i][j]][c[i+1][j]]=1;
if(j>0 && str[i][j-1]=='#') a[c[i][j]][c[i][j-1]]=1;
if(j<n-1 && str[i][j+1]=='#') a[c[i][j]][c[i][j+1]]=1;
}

ans=0;
for(i=0;i<k;i++)
{
memset(flag,0,sizeof(flag));
if(Find(i)) ans++;
}
printf("Case %d: ",w++);
printf("%d\n",ans/2);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: