POJ - 2226 Muddy Fields 二分图 最小点覆盖

题目大意:有一个n * m 大的牧场,牧场的土地分为两种,一种是很泥泞的,一种是相对比较干燥的

因为牧场里面的动物不喜欢泥泞的地方,所以牧场主想用些东西把这些泥泞的地方盖起来。

牧场主用一种宽度为1,长度不限的材料来覆盖这些泥泞的地方

问至少需要使用多少次这种材料,才可以把所有泥泞的地方盖起来

解题思路:刚开始没审对题目,上面所写的就是我刚开始认为的题意,所以我定势思维,以为这题和POJ - 3041 Asteroids一样,所以WA了两发

后来仔细看了一下,看漏了一个条件,那就是不能把相对干燥的地方也给覆盖掉。所以两题的区别就出来了,就是构造点集不一样,但解题的思路还是一样的,求出最小点覆盖就可以了

点集如何构造呢,只要不能连续的,都是属于不同的,这样就得重新设置一个变量来计算有多少行和多少列了

#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
const int N = 1010;
const int maxn = 60;
vector<int> row[N];
int n, m, num_r, new_row[maxn][maxn], new_col[maxn][maxn], vis[N], link[N];
char str[maxn][maxn];

void init() {
    num_r = 1;
    for(int i = 1; i <= n; i++)
        scanf("%s", str[i]);

    bool flag;
    for(int i = 1; i <= n; i++) {
        if(!flag)
            num_r++;
        flag = true;
        for(int j = 0; j < m; j++) {
            if(str[i][j] == ‘*‘) {
                new_row[i][j+1] = num_r;
                flag = false;
            }
            else if(str[i][j] == ‘.‘ && !flag){
                num_r++;
                flag = true;
            }
        }
    }

    for(int i = 1; i <= num_r; i++)
        row[i].clear();

    int cnt = 1;
    for(int i = 0; i < m; i++) {
        if(!flag)
            cnt++;
        flag = true;
        for(int j = 1; j <= n; j++) {
            if(str[j][i] == ‘*‘) {
                new_col[j][i+1] = cnt;
                flag = false;
            }else if(str[j][i] == ‘.‘ && !flag){
                flag = true;
                cnt++;
            }
        }
    }
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
            if(str[i][j-1] == ‘*‘)
                row[new_row[i][j]].push_back(new_col[i][j]);

    memset(link, 0, sizeof(link));
}

bool dfs(int u){
    for(int i = 0; i < row[u].size(); i++) {
        if(vis[row[u][i]])
            continue;
        vis[row[u][i]] = 1;
        if(!link[row[u][i]] || dfs(link[row[u][i]])) {
            link[row[u][i]] = u;
            return true;
        }
    }
    return false;
}

void hungary() {
    int ans = 0;
    for(int i = 1; i <= num_r; i++) {
        memset(vis,0,sizeof(vis));
        if(dfs(i))
            ans++;
    }
    printf("%d\n", ans);
}

int main() {
    while(scanf("%d%d", &n, &m) != EOF) {
        init();
        hungary();
    }
    return 0;
}
时间: 2024-09-30 14:35:05

POJ - 2226 Muddy Fields 二分图 最小点覆盖的相关文章

poj 2226 Muddy Fields(二分图最小点覆盖)

B - Muddy Fields Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 2226 Description Rain has pummeled the cows' field, a rectangular grid of R rows and C columns (1 <= R <= 50, 1 <= C <

poj 2226 Muddy Fields(最小点覆盖+巧妙构图)

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

poj 2226 Muddy Fields(最小点覆盖)

题意: M*N的矩阵,每个格不是*就是#.     *代表水坑,#代表草地. 农民要每次可以用一块宽为1,长不限的木板去铺这个矩阵.要求这块木板不能覆盖草地.木板可以重复覆盖(即一块木板与另一块木板有交叉重叠的部分). 问农民最少需要操作多少次可以覆盖所有的水坑. 思路 : 与Battle Ships那题非常像,代码也几乎一样. 对于每一行,可以分成一段一段的水坑,将其视为一个一个点,作为左部X集合中的点. 对于每一列同理. 对于每一个水坑,将其看作一条线,将其在左部X集合中的位置和在右部Y集合

poj 2226 Muddy Fields(合理建图+二分匹配)

1 /* 2 题意:用木板盖住泥泞的地方,不能盖住草.木板任意长!可以重叠覆盖! '*'表示泥泞的地方,'.'表示草! 3 思路: 4 首先让我们回忆一下HDU 2119 Matrix这一道题,一个矩阵中只有0, 1,然后让我们通过选择一行,或者 5 是一列将其所在行的或者所在列的 1全部删掉,求出最少需要几步? 6 7 这道题的思路就是:将行标 和 列标值为1的建立一条边!通过匈牙利算法可以得到这个二分图的最大匹配数 8 最大匹配数==最小顶点覆盖数!最小顶点覆盖就是用最少的点覆盖了这个二分图

POJ 2226 Muddy Fields(二分匹配 巧妙的建图)

题目链接:http://poj.org/problem?id=2226 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 co

POJ - 1325 Machine Schedule 二分图 最小点覆盖

题目大意:有两个机器,A机器有n种工作模式,B机器有m种工作模式,刚开始两个机器都是0模式,如果要切换模式的话,机器就必须的重启 有k个任务,每个任务都可以交给A机器的i模式或者B机器的j模式完成,问要重启多少次机器才能完成任务 解题思路:两个机器的点分为两个点集,点集之间的关系就是任务了,要将所有任务都完成,就要将所有边都覆盖掉,所以就是求最小点覆盖了. 这里有一个点要注意,如果所有任务中都有一个0,那么机器就不用重启了,重启次数就为0了(因为刚开始都是0) #include<cstdio>

poj 2226 二分图 最小点覆盖 , 最大流

题目就是问如何用最小的板覆盖所有的草地.可以横着放,也可以竖着放,允许一个草地放多个点. 建图方法就是 每个横向的草地作为X,纵向连续的草地作为Y.     X连接Y的边表示,  这里有他们的公共点.. 很显然,覆盖所有草地,就是覆盖所有的边 ,二分图中,最小点覆盖 = 最大匹配 = =其实如果存在一条边未被选中的节点覆盖,则必然存在一条对应的增广路径 //tpl //ipqhjjybj_tpl.h //header.h #include <cstdio> #include <cstdl

POJ2226 Muddy Fields(二分图最小点覆盖集)

题目给张R×C的地图,地图上*表示泥地..表示草地,问最少要几块宽1长任意木板才能盖住所有泥地,木板可以重合但不能盖住草地. 把所有行和列连续的泥地(可以放一块木板铺满的)看作点且行和列连续泥地分别作为XY部,每一块泥地看作边.这样就构造出了一个二分图. 那么,问题就是在这个二分图中就是选出最少的点覆盖所有的边,即二分图最小点覆盖集,而二分图最小点覆盖集=二分图最大匹配. 1 #include<cstdio> 2 #include<cstring> 3 #include<qu

Asteroids POJ - 3041 二分图最小点覆盖

Asteroids POJ - 3041 Bessie wants to navigate her spaceship through a dangerous asteroid field in the shape of an N x N grid (1 <= N <= 500). The grid contains K asteroids (1 <= K <= 10,000), which are conveniently located at the lattice point