zoukankan      html  css  js  c++  java
  • poj 2226 Muddy Fields

    Muddy Fields
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 10807   Accepted: 4015

    Description

    Rain has pummeled the cows' field, a rectangular grid of R rows and C columns (1 <= R <= 50, 1 <= C <= 50). While good for the grass, the rain makes some patches of bare earth quite muddy. The cows, being meticulous grazers, don't want to get their hooves dirty while they eat. 

    To prevent those muddy hooves, Farmer John will place a number of wooden boards over the muddy parts of the cows' field. Each of the boards is 1 unit wide, and can be any length long. Each board must be aligned parallel to one of the sides of the field. 

    Farmer John wishes to minimize the number of boards needed to cover the muddy spots, some of which might require more than one board to cover. The boards may not cover any grass and deprive the cows of grazing area but they can overlap each other. 

    Compute the minimum number of boards FJ requires to cover all the mud in the field.

    Input

    * Line 1: Two space-separated integers: R and C 

    * Lines 2..R+1: Each line contains a string of C characters, with '*' representing a muddy patch, and '.' representing a grassy patch. No spaces are present.

    Output

    * Line 1: A single integer representing the number of boards FJ needs.

    Sample Input

    4 4
    *.*.
    .***
    ***.
    ..*.
    

    Sample Output

    4
    

    Hint

    OUTPUT DETAILS: 

    Boards 1, 2, 3 and 4 are placed as follows: 
    1.2. 
    .333 
    444. 
    ..2. 
    Board 2 overlaps boards 3 and 4.
     
    题意:下雨之后农场某些土地泥泞了,牛不喜欢吃泥泞的草,约翰准备将这些泥泞的土地用宽度为1,长度不限的木板覆盖起来(木板只能平行于农场的长或宽来放置),问至少需要多少木板才可以把所有泥泞的土地都覆盖。
    思路:对于土地上每一个‘*’,找找横向需要哪块木板去覆盖,竖向又需要那块木板来覆盖。
    以题目为例:全是横向木板的放法:1 0 2 0数字是木板的编号,譬如‘333’就是一块木板,全是竖向木板:1 0 4 0
                                                            0 3 3 3                                                                                               0 3 4 5
                                                            4 4 4 0                                                                                               2 3 4 0
                                                            0 0 5 0                                                                                               0 0 4 0
    那么譬如第一行第二个‘*’的位置如果用横向木板,就用横向第二块木板来覆盖,或者竖向第4块来覆盖。即可连接这两块木板,如此操作可构成二分图,图中两边的点代表横向竖向的木板,连边则代表一块泥泞的‘*’,对于每一条边而言我们至少要取到这条边的其中一个顶点,并且要使得取到的这个顶点集合尽量的小,就是求最小顶点覆盖。
    AC代码:
    #define _CRT_SECURE_NO_DEPRECATE
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #include<set>
    #include<vector>
    #include<cstring>
    #include<string>
    using namespace std;
    #define INF 0x3f3f3f3f
    const int N_MAX = 2500+100,R_MAX=50+5;
    int V;//点的个数
    vector<int>G[N_MAX];
    int match[N_MAX];
    bool used[N_MAX];
    void add_edge(int u, int v) {
        G[u].push_back(v);
        G[v].push_back(u);
    }
    
    bool dfs(int v) {
        used[v] = true;
        for (int i = 0; i < G[v].size(); i++) {
            int u = G[v][i], w = match[u];
            if (w < 0 || !used[w] && dfs(w)) {
                match[v] = u;
                match[u] = v;
                return true;
            }
        }
        return false;
    }
    
    int bipartite_matching() {
        int res = 0;
        memset(match, -1, sizeof(match));
        for (int v = 0; v < V; v++) {
            if (match[v] < 0) {
                memset(used, 0, sizeof(used));
                if (dfs(v))
                    res++;
            }
        }
        return res;
    }
    char field[N_MAX][N_MAX];
    int mark_x[N_MAX][N_MAX],mark_y[N_MAX][N_MAX];
    
    int R, C;
    int main() {
        while (scanf("%d%d",&R,&C)!=EOF) {
            memset(mark_x, -1, sizeof(mark_x));
            memset(mark_y, -1, sizeof(mark_y));
            for (int i = 0; i < R; i++){
                    char c;
                    scanf("%s",field[i]);
                }
            int num = 0; bool flag = 0,New=0;
            for (int i = 0; i < R;i++) {
                for (int j = 0; j < C;j++) {
                    if (field[i][j] == '*') {
                        num++;
                        while (j<C&&field[i][j]=='*') {
                            mark_x[i][j] = num;
                            j++;
                        }
                    }
                }
            }
    
    
             num = 0,flag=0, New = 0;
             for (int i = 0; i < C; i++) {
                 for (int j = 0; j < R; j++) {
                     if (field[j][i] == '*') {
                         num++;
                         while (j<R&&field[j][i] == '*') {
                             mark_y[j][i] = num;
                             j++;
                         }
                     }
                 }
             }
    
    
            V =N_MAX;
            //1~N_MAX/2:横向木板
            //N_MAX/2+1~N_MAX:纵向木板
            for (int i = 0; i < R; i++) {
                for (int j = 0; j < C; j++) {
                    if (field[i][j] == '*') {
                        add_edge(mark_x[i][j],mark_y[i][j]+N_MAX/2);
                    }
                }
        }
    
            printf("%d
    ",bipartite_matching());
            for (int i = 0; i < V;i++) {
                G[i].clear();
            }
        }
        return 0;
    }
  • 相关阅读:
    Logstash-input-jdbc同步mysql数据到ES - sql_last_value
    filebeat7.5.2 在 windows server 2008 R2 设置系统服务报错
    mysql8.0.19压缩版安装
    不是RESTful不好,是你姿势有问题
    logback运行时动态创建日志文件
    jpa 主键重复导致查询list的数据总是重复第一条数据
    解决MySQL Workbench导出低版本MySQL时报错Unknown table ‘column_statistics’ in information_schema的问题
    windows10系统修改JDK版本后配置环境变量不生效怎么办
    application.properties 中文乱码问题解决
    JAVA抽象类和抽象方法(abstract)
  • 原文地址:https://www.cnblogs.com/ZefengYao/p/7266919.html
Copyright © 2011-2022 走看看