首页 > 代码库 > BZOJ 1735: [Usaco2005 jan]Muddy Fields 泥泞的牧场
BZOJ 1735: [Usaco2005 jan]Muddy Fields 泥泞的牧场
Description
大雨侵袭了奶牛们的牧场.牧场是一个R * C的矩形,其中1≤R,C≤50.大雨将没有长草的土地弄得泥泞不堪,可是小心的奶牛们不想在吃草的时候弄脏她们的蹄子. 为了防止她们的蹄子被弄脏,约翰决定在泥泞的牧场里放置一些木板.每一块木板的宽度为1个单位,长度任意.每一个板必须放置在平行于牧场的泥地里. 约翰想使用最少的木板覆盖所有的泥地.一个木板可以重叠在另一个木板上,但是不能放在草地上.
Input
第1行:两个整数R和C.
第2到R+1行:每行C个字符,其中“*’代表泥地,“.”代表草地.
Output
最少需要多少木板.
题解:
?不能盖住好地,那么宽为1的木板只能放在行、列连通块里。
?所以行、列连通块对应左、右部中的点,泥地对应边。
?求二分图最小覆盖就是答案。
二分图最小点覆盖==最大匹配
代码:
#include<cstdio>#include<cstring>#include<algorithm>//by zrt//problem:using namespace std;typedef long long ll;const double eps(1e-10);int R,C,n;char s[60][60];int link[1005];int cover[1005];int H[1005],X[1000050],P[1000050],tot;inline void add(int x,int y){ P[++tot]=y;X[tot]=H[x];H[x]=tot;}bool find(int x){ for(int i=H[x];i;i=X[i]){ if(cover[P[i]]) continue; cover[P[i]]=1; int q=link[P[i]]; link[P[i]]=x; if(q==-1||find(q)) return 1; link[P[i]]=q; } return 0;}int xn,yn;int a[60][60],b[60][60];int main(){ #ifdef LOCAL freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif memset(link,-1,sizeof link); scanf("%d%d",&R,&C); for(int i=0;i<R;i++){ scanf("%s",s[i]); } for(int i=0;i<R;i++){ for(int j=0;j<C;j++){ if(s[i][j]==‘*‘){ if(j>0&&s[i][j-1]==‘*‘){ a[i][j]=a[i][j-1]; }else a[i][j]=++yn; if(i>0&&s[i-1][j]==‘*‘){ b[i][j]=b[i-1][j]; }else b[i][j]=++xn; } } } for(int i=0;i<R;i++){ for(int j=0;j<C;j++){ if(s[i][j]==‘*‘){ add(a[i][j],b[i][j]); } } } n=yn; int ans(0); for(int i=1;i<=n;i++){ memset(cover,0,sizeof cover); if(find(i)) ans++; } printf("%d\n",ans); return 0;}
BZOJ 1735: [Usaco2005 jan]Muddy Fields 泥泞的牧场
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。