[Usaco2005 Jan]Muddy Fields泥泞的牧场

时间:2020-04-20
本文章向大家介绍[Usaco2005 Jan]Muddy Fields泥泞的牧场,主要包括[Usaco2005 Jan]Muddy Fields泥泞的牧场使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。


雨连续不断的击打了放牛的牧场,一个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); 
}

  

原文地址:https://www.cnblogs.com/cutemush/p/12737009.html