POJ 2226 最小点覆盖(经典建图)

Muddy Fields

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 8881   Accepted: 3300

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

题目意思:

一个n*m的图,其中‘.‘表示平地,‘*‘水池。现用一些宽为1个单位,长度不限的木板覆盖所有的水池(某个水池可以被覆盖多次)。问所用木板最少为多少。

思路:

每个水池可以被横着覆盖也可以被竖着覆盖,那么题目就成为选用一些覆盖策略使得所有点被横着覆盖或者被竖着覆盖,而某些点被横着或竖着覆盖可以影响与其横着连续的点或竖着连续的点。那么横着处理一下图如同题目中Hint中,同理竖着处理一下图。每个点有两个数字,一个是横着状态数字,另一个是竖着状态数字,连边后建图,就是最小点覆盖了。

代码:

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <iostream>
  5 #include <vector>
  6 #include <queue>
  7 #include <cmath>
  8 #include <set>
  9 using namespace std;
 10
 11 #define N 50
 12
 13 int max(int x,int y){return x>y?x:y;}
 14 int min(int x,int y){return x<y?x:y;}
 15 int abs(int x,int y){return x<0?-x:x;}
 16
 17 int n, m;
 18 vector<int>ve[N*N];
 19 int from[N*N];
 20 bool visited[N*N];
 21 char map[N][N];
 22 int map1[N][N];
 23 int map2[N][N];
 24
 25 int march(int u){
 26     int i, v;
 27     for(i=0;i<ve[u].size();i++){
 28         v=ve[u][i];
 29         if(!visited[v]){
 30             visited[v]=true;
 31             if(from[v]==-1||march(from[v])){
 32                 from[v]=u;
 33                 return 1;
 34             }
 35         }
 36     }
 37     return 0;
 38 }
 39
 40 main()
 41 {
 42     int i, j, k;
 43     while(scanf("%d %d",&n,&m)==2){
 44         for(i=0;i<n;i++) scanf("%s",map[i]);
 45         memset(map1,-1,sizeof(map1));
 46         memset(map2,-1,sizeof(map2));
 47         int num=1;
 48         int maxh=0;
 49         //横着处理
 50         for(i=0;i<n;i++){
 51             for(j=0;j<m;j++){
 52                 if(map[i][j]==‘*‘){
 53                     if(j==0) map1[i][j]=num;
 54                     else{
 55                         if(map[i][j-1]==‘*‘) map1[i][j]=map1[i][j-1];
 56                         else map1[i][j]=num;
 57                     }
 58                 }
 59                 else {
 60                     if(j<m-1&&map[i][j+1]==‘*‘) num++;
 61                 }
 62             }
 63             num++;
 64             maxh=max(maxh,num);
 65         }
 66         //竖着处理
 67         num=1;
 68         for(j=0;j<m;j++){
 69             for(i=0;i<n;i++){
 70                 if(map[i][j]==‘*‘){
 71                     if(i==0) map2[i][j]=num;
 72                     else{
 73                         if(map[i-1][j]==‘*‘) map2[i][j]=map2[i-1][j];
 74                         else map2[i][j]=num;
 75                     }
 76                 }
 77                 else{
 78                     if(i<n-1&&map[i+1][j]==‘*‘) num++;
 79                 }
 80             }
 81             num++;
 82             maxh=max(maxh,num);
 83         }
 84         //建二分图
 85         for(i=0;i<maxh;i++) ve[i].clear();
 86         for(i=0;i<n;i++){
 87             for(j=0;j<m;j++){
 88                 if(map1[i][j]!=-1&&map2[i][j]!=-1){
 89                     ve[map1[i][j]].push_back(map2[i][j]);
 90                 }
 91             }
 92         }
 93         //二分匹配
 94         memset(from,-1,sizeof(from));
 95         num=0;
 96         for(i=0;i<maxh;i++){
 97             memset(visited,false,sizeof(visited));
 98             if(march(i)) num++;
 99         }
100         printf("%d\n",num);
101     }
102 }
时间: 2024-12-23 12:55:55

POJ 2226 最小点覆盖(经典建图)的相关文章

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

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

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, t

POJ 3020 Antenna Placement(二分图建图训练 + 最小路径覆盖)

题目链接:http://poj.org/problem?id=3020 Antenna Placement Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6692   Accepted: 3325 Description The Global Aerial Research Centre has been allotted the task of building the fifth generation of mobi

POJ 1149 PIGS(最大流+建图)

题目链接:http://poj.org/problem?id=1149 题意:M个猪圈,N个顾客,每个顾客有一些的猪圈的钥匙,只能购买能打开的猪圈里的猪,而且要买一定数量的猪,每个猪圈有已知数量的猪, 但是猪圈可以重新打开,将猪的个数,重新分配,但是只能将猪往当前打开状态的猪圈里赶,以达到卖出的猪的数量最多. 思路:还是4部分,源点->猪圈->猪圈->汇点 Accepted 976K 63MS C++ 能用EK水的,当然用EK水 #include <iostream> #in

二分图最大匹配,最小路径覆盖,最小点覆盖,最大独立集,最小边覆盖与建图方法

转载请注明出处(别管写的好坏,码字也不容易):http://blog.csdn.net/hitwhacmer1 前言:         有自己写的,有摘的别人的,前面是摘的,也是无心整理,出错是难免的,反正我都不会证明,智人见智,别被我误导了. §1图论点.边集和二分图的相关概念和性质 点覆盖.最小点覆盖 点覆盖集即一个点集,使得所有边至少有一个端点在集合里.或者说是"点" 覆盖了所有"边"..极小点覆盖(minimal vertex covering):本身为点覆

HDU 3376--Matrix Again【最大费用最大流 &amp;&amp; 经典建图】

Matrix Again Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others) Total Submission(s): 3457    Accepted Submission(s): 1020 Problem Description Starvae very like play a number game in the n*n Matrix. A positive intege

POJ 2112 最大流+二分+(建图:最重要的)

Optimal Milking Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 12521   Accepted: 4524 Case Time Limit: 1000MS Description FJ has moved his K (1 <= K <= 30) milking machines out into the cow pastures among the C (1 <= C <= 200) co

POJ-3020 Antenna Placement---二分图匹配&amp;最小路径覆盖&amp;建图

题目链接: https://vjudge.net/problem/POJ-3020 题目大意: 一个n*m的方阵 一个雷达可覆盖两个*,一个*可与四周的一个*被覆盖,一个*可被多个雷达覆盖问至少需要多少雷达能把所有的*覆盖 解题思路: 把每个*城市编号,然后每相邻两个城市之间连线.这里求最少多少个雷达可以覆盖完*,就是二分图匹配中的最小路径覆盖数,但是这里的图的边是双向的.举个例子 o*o **o ooo 这里可以编号成 010 230 000 那么有边<1,3><3,1><

poj 3678 Katu Puzzle 2-SAT 建图入门

Description Katu Puzzle is presented as a directed graph G(V, E) with each edge e(a, b) labeled by a boolean operator op (one of AND, OR, XOR) and an integer c (0 ≤ c ≤ 1). One Katu is solvable if one can find each vertex Vi a value Xi (0 ≤ Xi ≤ 1) s