题意:一个农夫想为一个有低洼地区的草地铺木板,木板的长度不定,宽度为1格,铺下的木板不能盖到任何一处草地,问至少需要多少木板。
解题思路:这题想了很久,一直想不出来,可能最近的是失恋导致的效率问题。这题的构图十分精妙,就例子来说,
给出的草地是*.*..******...*.假设只 横 着放木板的话,我们把木板编个号1.2..333444...5.假设只 竖 着放木板的话,我们把木板编个号1.4..345234...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);}
}