题意:一个农夫想为一个有低洼地区的草地铺木板,木板的长度不定,宽度为1格,铺下的木板不能盖到任何一处草地,问至少需要多少木板。
解题思路:这题想了很久,一直想不出来,可能最近的是失恋导致的效率问题。这题的构图十分精妙,就例子来说,
给出的草地是
*.*.
.***
***.
..*.
假设只 横 着放木板的话,我们把木板编个号
1.2.
.333
444.
..5.
假设只 竖 着放木板的话,我们把木板编个号
1.4.
.345
234.
..4.
那么现在对于每个低洼地区,要么被不同的横木板覆盖,要么被不同的竖木板覆盖,而所有低洼地区只要被覆盖一遍就行了,所以我们对横竖木板进行建立二部图,当某一横木板与某一竖木板有共同覆盖区域时(注意横木板不可能与横木板有共同覆盖区,竖木板也是),就加一条边,那么问题变为求这个二部图的最小点覆盖集了。
这题数组开大一点...开到900以上吧
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int x,y,mj[1005][1005],n,m,c[1005][1005],r[1005][1005],result[1005],flag[1005],p,ans;
char mjc[1005][1005];
bool find(int i)
{
int j;
for(j=1;j<=p;j++)
{
if(mj[i][j]!=0&&flag[j]==0)
{
flag[j]=1;
if(result[j]==0||find(result[j]))
{
result[j]=i;
return 1;
}
}
}
return 0;
}
int main()
{
int i,j,f;
while(scanf("%d %d",&n,&m)!=EOF)
{
memset(mj,0,sizeof(mj));
memset(result,0,sizeof(result));
memset(c,0,sizeof(c));
memset(r,0,sizeof(r));
getchar();
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
mjc[i][j]=getchar();
getchar();
}
int q=0;
for(j=1;j<=m;j++)
{
f=0;
for(i=1;i<=n;i++)
{
if(mjc[i][j]=='*')
{
if(f==0){q++;f=1;c[i][j]=q;}
else
{
c[i][j]=q;
}
}
else
{
c[i][j]=0;
f=0;
}
}
}
p=0;
for(i=1;i<=n;i++)
{
f=0;
for(j=1;j<=m;j++)
{
if(mjc[i][j]=='*')
{
if(f==0){p++;f=1;r[i][j]=p;}
else
{
r[i][j]=p;
}
}
else
{
r[i][j]=0;
f=0;
}
}
}
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
mj[c[i][j]][r[i][j]]=1;
ans=0;
for(i=1;i<=q;i++)
{
memset(flag,0,sizeof(flag));
if(find(i)) ans++;
}
printf("%d\n",ans);
}
}