标签: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