标签:clu can scan pac link std 长度 fine png
雨连续不断的击打了放牛的牧场,一个R行C列的格子(1 <= R <= 50,
1 <= C <= 50)。虽然这对草来说是件好事,但这却使得一些没有草遮盖的土地
变得很泥泞。牛们是很小心的食草动物;他们不想在吃草时把蹄子弄脏。
为了避免它们把蹄子弄脏,农夫约翰要在那些泥泞的地方铺上木板子。每个1个
单位宽,长度任意。每个板子都必须放到与牧场一边平行。
农夫约翰希望用最少的板子来覆盖泥泞的部分。一些地方可能需要多于一块板
子来覆盖。木板不可以遮住草地,剥夺牛吃草的地方,但是他们可以相互重叠。
计算最少需要多少块板子来覆盖所有的泥地。
Input
* 第一行:两个整数R和C,由空格隔开。
* 第2到第R+1行:每行为一个长度为C的字符串。‘*‘代表泥地,‘.‘代表草地。
无空格。
Output
* 第一行:一个整数,其值为最少需要的板子数目
Sample Input
4 4
*.*.
.***
***.
..*.
Sample Output
4
输出细节:
板子 1, 2, 3 和 4 是这样摆放的:
1.2.
.333
444.
..2.
板子2与3,4重叠。
Sol:
把每行中的连续泥地看成一个点(X集合),每列中的连续泥地看成一个点(Y集合),如果两个有交点就连一条边,此边就是一块泥地,于是题目顺利转化成最小点覆盖集问题。
对于样例:
行编号如下
1020
0333
4440
0050
列编号如下
1020
0324
5320
0020
构图如下
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<queue> using namespace std; #define inf 2147483647 #pragma GCC optimize (2) void read(int &x){ int f=1;char ch=getchar();x=0; for(;!isdigit(ch);ch=getchar())if(ch==‘-‘)f=-f; for(;isdigit(ch);ch=getchar())x=x*10+ch-‘0‘;x*=f; } #define maxm 1000050 #define maxn 100 int a[60][60],dx,dy,link[10005],m,n,b[60][60]; char s[60][60]; int head[1005],tot=1,cover[1005]; struct node{ int to,next; }e[maxm]; void add(int x,int y) { e[tot].to=y; e[tot].next=head[x]; head[x]=tot++; } bool find(int x) { for(int p=head[x];p;p=e[p].next) { int v=e[p].to; if(cover[v]) continue; cover[v]=1; int q=link[v];link[v]=x; if(q==-1||find(q)) return 1; link[v]=q; } return 0; } int main() { memset(link,-1,sizeof(link)); read(m),read(n); for(int i=0;i<m;i++) //M行 scanf("%s",s[i]); for(int i=0;i<m;i++) //M行 { for(int j=0;j<n;j++) //N列 { if(s[i][j]==‘*‘) { if(j>0&&s[i][j-1]==‘*‘) a[i][j]=a[i][j-1]; else a[i][j]=++dy; if(i>0&&s[i-1][j]==‘*‘) b[i][j]=b[i-1][j]; else b[i][j]=++dx; } } } for(int i=0;i<m;i++) for(int j=0;j<n;j++) if(s[i][j]==‘*‘) add(a[i][j],b[i][j]); int t=dy,sum=0; for(int i=1;i<=t;i++) { memset(cover,0,sizeof(cover)); if(find(i)) sum++; } printf("%d\n",sum); }
[Usaco2005 Jan]Muddy Fields泥泞的牧场
标签:clu can scan pac link std 长度 fine png
原文地址:https://www.cnblogs.com/cutemush/p/12737009.html