POJ-2226-Muddy Fields

来源:互联网 发布:网络电话机终端 编辑:程序博客网 时间:2024/04/30 20:15

POJ-2226-Muddy Fields

http://poj.org/problem?id=2226

建图很巧妙,一块木板能覆盖一行或一列的土地,先按行来铺木块,再按列来铺木块

*.*.   按行1  0  2  0    按列 1  0  4  0

.***           0  3  3  3             0  3  4  5

***.           4  4  4  0             2  3  4  0

..*.            0   0  5  0            0  0  4  0

对每个*的行和列连一条边,构成二分图,题目便转化为求最小点覆盖,即最大二分匹配

#include<cstdio>#include<cstring>#include<cstdlib>using namespace std;int n1,n2;char map[1005][1005];  //数组开大点,不然会WAint mapx[1005][1005],mapy[1005][1005];int ma[1005][1005];int result[1005],visit[1005];int x,y;int find(int a){int i;for(i=1;i<=y;i++){if(!visit[i]&&ma[a][i]){visit[i]=1;if(!result[i]||find(result[i])){result[i]=a;return 1;}}}return 0;}int main(){int i,j,ans;while(scanf("%d%d",&n1,&n2)!=EOF){for(i=0;i<n1;i++)scanf("%s",map[i]);memset(mapx,0,sizeof(mapx));memset(mapy,0,sizeof(mapy));x=0;for(i=0;i<n1;i++)for(j=0;j<n2;j++)if(map[i][j]=='*'){   ++x;   while(j<n2&&map[i][j]=='*')   {   mapx[i][j]=x;   j++;   }    }y=0;for(j=0;j<n2;j++)for(i=0;i<n1;i++)if(map[i][j]=='*'){    ++y;while(i<n1&&map[i][j]=='*'){mapy[i][j]=y;i++;}}for(i=0;i<n1;i++)for(j=0;j<n2;j++)ma[mapx[i][j]][mapy[i][j]]=1;ans=0;memset(result,0,sizeof(result));for(i=1;i<=x;i++){memset(visit,0,sizeof(visit));ans+=find(i);}printf("%d\n",ans);}return 0;}