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 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.

Source

USACO 2005 January Gold

题目大意:用木板将‘*‘覆盖,同一行或同一列的‘*‘可以用一块木板覆盖,‘.‘不能被覆盖。问最少用多少块木板可以把全部的‘*‘覆盖?
木板只能够覆盖连续的横着的泥巴和竖着的泥巴,中间有草地就要隔开

解题思路:二分匹配的经典构图题目
构图思路:
将横着的木板和看成一边的点的集合,将竖着的木板看成另外一边的点的集合,如果他们相交于一点就连边
如果要把所有的泥巴覆盖,又要所需要的木板最少,那么就是求最小点覆盖

所以用匈牙利求最大匹配数即可

构图的代码要好好再看看!

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 #define N 560
 6 int n,m;
 7
 8 char mp[N][N];
 9 int cnt[N][N];
10 int cnt1[N][N];
11 int fina[N][N];
12 int match[N];
13 int vis[N];
14 int tmp,tmp1;
15 bool dfs(int x){
16     for(int i=1;i<=tmp1;i++){
17         if(!vis[i] && fina[x][i]) {
18             vis[i]=1;
19             if(match[i]==-1 || dfs(match[i])){
20                 match[i]=x;
21                 return true;
22             }
23         }
24     }
25     return false;
26 }
27 void solve(){
28     memset(match,-1,sizeof(match));
29     int ans=0;
30     for(int i=1;i<=tmp;i++){
31         memset(vis,0,sizeof(vis));
32         if(dfs(i)){
33             ans++;
34         }
35     }
36     printf("%d\n",ans);
37
38 }
39 int main()
40 {
41     while(scanf("%d%d",&n,&m)==2){
42         memset(mp,0,sizeof(mp));
43         for(int i=0;i<n;i++){
44             scanf("%s",mp[i]);
45         }
46         memset(cnt,-1,sizeof(cnt));
47         memset(cnt1,-1,sizeof(cnt1));
48         tmp=0;
49         for(int i=0;i<n;i++){
50             int flag=0;
51             for(int j=0;j<m;j++){
52
53                 if(flag==0 && mp[i][j]==‘*‘){
54                     flag=1;
55                     cnt[i][j]=++tmp;
56                 }
57                 else if(flag==1 && mp[i][j]==‘*‘){
58                     cnt[i][j]=tmp;
59                 }
60                 else if(mp[i][j]==‘.‘){
61                     flag=0;
62                 }
63             }
64         }
65
66         tmp1=0;
67         for(int j=0;j<m;j++){
68             int flag=0;
69             for(int i=0;i<n;i++){
70                 if(flag==0 && mp[i][j]==‘*‘){
71                     flag=1;
72                     cnt1[i][j]=++tmp1;
73                 }
74                 else if(flag==1 && mp[i][j]==‘*‘){
75                     cnt1[i][j]=tmp1;
76                 }
77                 else if(mp[i][j]==‘.‘){
78                     flag=0;
79                 }
80             }
81         }
82         memset(fina,0,sizeof(fina));
83         for(int i=0;i<n;i++){
84             for(int j=0;j<m;j++){
85                 if(cnt[i][j]!=-1 && cnt1[i][j]!=-1){
86                     fina[cnt[i][j]][cnt1[i][j]]=1;
87                 }
88             }
89         }
90
91         solve();
92     }
93     return 0;
94 }

时间: 2024-08-02 19:09:24

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(合理建图+二分匹配)

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

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

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

poj 2226 Muddy Fields(最小点覆盖)

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

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 1463 Strategic game 最小点覆盖集(树形dp)

点击打开链接 Strategic game Time Limit: 2000MS   Memory Limit: 10000K Total Submissions: 6105   Accepted: 2808 Description Bob enjoys playing computer games, especially strategic games, but sometimes he cannot find the solution fast enough and then he is v

POJ 3401 Asteroids 求最小点覆盖集

把行和列都看做是点,小行星看成是边的话,那么这个显然就是求一个最小点覆盖集的问题. 最小点覆盖 == 最大匹配 #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #inc

POJ 3041 Asteroids (二分图最小点覆盖)

题目链接:http://poj.org/problem?id=3041 在一个n*n的地图中,有m和障碍物,你每一次可以消除一行或者一列的障碍物,问你最少消除几次可以将障碍物全部清除. 用二分图将行(左边)和列(右边)用障碍物联系起来,比如(2,3)有个障碍物,那么左边的2和右边的3连边.边的个数就是障碍物的个数,点的个数就是次数,所以问题就变成了用少的点覆盖全部的边,也就是最小点覆盖问题.二分图中,最小点覆盖=最大匹配数. 1 //最小点覆盖 = 最大匹配 2 #include <iostre

poj 1325 Machine Schedule 最小点覆盖

题目链接:http://poj.org/problem?id=1325 As we all know, machine scheduling is a very classical problem in computer science and has been studied for a very long history. Scheduling problems differ widely in the nature of the constraints that must be satis