POJ 2226-Muddy Fields(二分图_最小点覆盖+神建图orz)

Muddy Fields

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 8434   Accepted: 3124

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

题意:“*”代表沼泽,“。”表示草坪。牛要回家,不能踩草坪,所以只能走沼泽,遇到有沼泽的地方就要主人铺板子,问最少铺多少板子。

思路:典型的二分图匹配中的最小点覆盖。但是不得不说这个建图简直太神奇了!反正我是想不出来,orz。

建图方式按照先行后列。

把行里面连在一起的坑连起来视为一个点,即一块横木板,编上序号

1 0 2 0

0 3 3 3

4 4 4 0

0 0 5 0

再按列做一次则为:

1 0 4 0

0 3 4 5

2 3 4 0

0 0 4 0

一个坑只能被横着的或者被竖着的木板盖住,将原图的坑的也标上不同的序号,一共九个坑

1 . 2 .

. 3 4 5

67 8 .

. . 9 .

比如7号坑可以被横着的4号木板和竖着的3号木板盖住,把每个点的对应的横木板(4)和竖木板(3)中间连一条边的话,则问题转化为 找尽量少的边把这些点都盖住

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
using namespace std;
int n,m;
int cnt1,cnt2;
int G[1010][1010];
int vis[1010];
int link[1010];
char map[110][110];
int m1[110][110];
int m2[110][110];
int dfs(int u)
{
        int i;
        for(i=0; i<cnt2; i++) {
                if(G[u][i]&&!vis[i]) {
                        vis[i]=1;
                        if(link[i]==-1|| dfs(link[i])) {
                                link[i] = u;
                                return 1;
                        }
                }
        }
        return 0;
}
void build_tu()
{
        int i,j;
        cnt1=cnt2=0;
        for(i=0; i<n; i++)
                for(j=0; j< m; j++) {
                        if(map[i][j]=='*') {
                                while(map[i][j]=='*') {
                                        m1[i][j]=cnt1;
                                        j++;
                                }
                                cnt1++;
                        }
                }
        for(i=0; i<m; i++)
                for(j=0; j<n; j++)	{
                        if(map[j][i]=='*') {
                                while(map[j][i]=='*') {
                                        m2[j][i]=cnt2;
                                        j++;
                                }
                                cnt2++;
                        }
                }
        /*for(i=1;i<=n;i++)
           for(j=1;j<=m;j++)
        {
           if(j==m)
               printf("%d\n",m1[i][j]);
           else
           printf("%d ",m1[i][j]);
        }
        for(i=1;i<=n;i++)
           for(j=1;j<=m;j++)
        {
           if(j==m)
               printf("%d\n",m2[i][j]);
           else
           printf("%d ",m2[i][j]);
        }*/
        for(i=0; i<n; i++)
                for(j=0; j<m; j++) {
                        if(map[i][j]=='*')
                                G[m1[i][j]][m2[i][j]]=1;
                }
}
int main()
{
        int i;
        int sum;
        while(~scanf("%d %d",&n,&m)) {
                sum=0;
                memset(G, 0, sizeof(G));
                memset(m1, 0, sizeof(m1));
                memset(m2, 0, sizeof(m2));
                memset(link,-1,sizeof(link));
                for(i=0; i<n; i++)
                        scanf("%s", map[i]);
                build_tu();
                for(i=0; i<cnt1; i++) {
                        memset(vis,0,sizeof(vis));
                        if(dfs(i)) {
                                //printf("%d---->",dfs(i));
                                sum++;
                        }
                }
                printf("%d\n", sum);
        }
        return 0;
}
时间: 2024-11-08 08:48:27

POJ 2226-Muddy Fields(二分图_最小点覆盖+神建图orz)的相关文章

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 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 二分图 最小点覆盖

题目大意:有一个n * m 大的牧场,牧场的土地分为两种,一种是很泥泞的,一种是相对比较干燥的 因为牧场里面的动物不喜欢泥泞的地方,所以牧场主想用些东西把这些泥泞的地方盖起来. 牧场主用一种宽度为1,长度不限的材料来覆盖这些泥泞的地方 问至少需要使用多少次这种材料,才可以把所有泥泞的地方盖起来 解题思路:刚开始没审对题目,上面所写的就是我刚开始认为的题意,所以我定势思维,以为这题和POJ - 3041 Asteroids一样,所以WA了两发 后来仔细看了一下,看漏了一个条件,那就是不能把相对干燥

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

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

poj 2226 Muddy Fields(最小点覆盖)

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

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 2239-Selecting Courses(二分图_最大匹配+哈希建图)

Selecting Courses Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8781   Accepted: 3922 Description It is well known that it is not easy to select courses in the college, for there is usually conflict among the time of the courses. Li Mi

二分图的最小点覆盖和最大独立集

一.二分图的最小点覆盖 无向图的最小点覆盖,就是选取图中最少的点使得每条边至少有一个端点被选中. 而二分图的最小点覆盖 = 最大匹配. 二.二分图的最大独立集 无向图的最大独立集,就是从无向图中选取尽量多的点,这些点两两不邻接. 而二分图的最大独立集 = 点总数 - 最大匹配. 解析见链接:http://hihocoder.com/problemset/problem/1127

POJ 3686 The Windy&#39;s【最小权匹配(神建图啊)】

大意:有n个任务m个机器,告诉你n*m的矩阵表示每个任务在每个机器上完成需要的时间 问所有任务完成的总时间最少?(比如第一个任务在第一分钟完成第二个任务在第二分钟完成   则总时间为1 + 2 = 3 分析: 该题自己做的时候没有思路 后来在网上搜题解,感觉建图真是太厉害了 假设最优情况下,个个任务需要的时间分别为a1, a2, a3, ……,an 那么总时间t = n * a1 + (n - 1) * a2 + ……+ 2 * an - 1 + an 也就是说只需要考虑系数就可以了 我们先假设