zoukankan      html  css  js  c++  java
  • [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
    ",sum); 
    }
    

      

  • 相关阅读:
    asm createdisk时提示没有权限
    webkit 模拟点击 winform
    .net中的反射(转载)
    wpf——三维学习1
    3dmax导出到blend或者vs中
    地理坐标系与投影坐标系
    Arcgis与CityEngine安装破解
    忘记Windows7登陆密码解决办法
    wpf的UserControl用户控件怎么添加到Window窗体中
    postgres索引创建、 存储过程的创建以及在c#中的调用
  • 原文地址:https://www.cnblogs.com/cutemush/p/12737009.html
Copyright © 2011-2022 走看看