poj2226Muddy Fields【最小点覆盖(建图的思路比较好)】

大意:如下图告诉你一个矩阵,让你用1 * x (x 为任意值) 的木板去铺符号*  可以覆盖

问最少多少木板能够把所有的*覆盖掉

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

Boards 1, 2, 3 and 4 are placed as follows: 1.2. .333 444. ..2. Board 2 overlaps boards 3 and 4.

分析:题目要求是把所有的点都覆盖掉回忆一下之前做过的这种类型的大概就是二分图的最小点覆盖或者最小边覆盖那么怎么建立二分图呢因为X是个不确定值所以我们尽量让X取值越大越好 也就是说每一个横向或纵向的*区域都可以看做是一个联通块那么只要把横向的连通块放在左集合,把纵向的连通块放在右集合 把点看左边那么只要所有的边被覆盖则就是覆盖掉所有的*了这样想来因为左右集合放的就是所求的连通块,那么只要求出最小点覆盖集即ok啦最小点覆盖集 = 二分图最大匹配

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <vector>
 5 using namespace std;
 6
 7 const int maxn = 55;
 8 int G[maxn * maxn / 2][maxn * maxn / 2];
 9
10 int vis[maxn * maxn / 2];
11 int Link[maxn * maxn / 2];
12 int n;
13 bool Find(int u) {
14     for(int i = 1; i <= n; i++) {
15         if(G[u][i] && !vis[i]) {
16             vis[i] = 1;
17             if(Link[i] == -1 || Find(Link[i])) {
18                 Link[i] = u;
19                 return true;
20             }
21         }
22     }
23     return false;
24 }
25
26 int solve() {
27     int cnt = 0;
28     memset(Link, -1, sizeof(Link));
29     for(int i = 1; i <= n; i++) {
30         memset(vis, 0, sizeof(vis));
31         if(Find(i)) cnt++;
32     }
33     return cnt;
34 }
35
36 char mat[maxn][maxn];
37 int vis1[maxn][maxn], vis2[maxn][maxn];
38 int main() {
39     int m;
40     for(int i = 0; i <= 50; i++) {
41         mat[0][i] = mat[i][0] = ‘.‘;
42     }
43     while(EOF != scanf("%d %d",&n, &m)) {
44         for(int i = 1; i <= n; i++) {
45             for(int j = 1; j <= m; j++) {
46                 scanf("\n%c",&mat[i][j]);
47             }
48         }
49         int tot1 = 1; int tot2 = 1;
50         memset(vis1, 0, sizeof(vis1)); memset(vis2, 0, sizeof(vis2));
51         for(int i = 1; i <= n; i++) {
52             for(int j = 1; j <= m; j++) {
53                 if(mat[i][j] == ‘*‘) {
54                     if(!vis1[i][j - 1]) {
55                         vis1[i][j] = tot1++;
56                     } else {
57                         vis1[i][j] = vis1[i][j - 1];
58                     }
59                     if(!vis2[i - 1][j]) {
60                         vis2[i][j] = tot2++;
61                     } else {
62                         vis2[i][j] = vis2[i - 1][j];
63                     }
64                 }
65             }
66         }
67         memset(G, 0, sizeof(G));
68         for(int i = 1; i <= n; i++) {
69             for(int j = 1; j <= m; j++) {
70                 if(mat[i][j] == ‘*‘) {
71                     G[vis1[i][j]][vis2[i][j]] = 1;
72                 }
73             }
74         }
75         n = max(tot1, tot2);
76         printf("%d\n",solve());
77     }
78     return 0;
79 }

poj2226Muddy Fields【最小点覆盖(建图的思路比较好)】

时间: 2024-10-14 04:04:47

poj2226Muddy Fields【最小点覆盖(建图的思路比较好)】的相关文章

bzoj 1412 [ZJOI2009]狼和羊的故事 最小割建图

题面 题目传送门 解法 把\(S\)集看作和羊连接,\(T\)看作和狼连接 然后就转化成了基本的最小割模型了 对于0的处理,可以把它放在羊和狼两排点的中间,由\(S\rightarrow\)羊\(\rightarrow0\rightarrow\)狼\(\rightarrow T\) 然后跑dinic即可 代码 #include <bits/stdc++.h> #define inf 1 << 30 #define N 110 using namespace std; templat

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

[BZOJ1391]解题报告|网络流的又一类建图&amp;Dinic的若干优化

1391: [Ceoi2008]order 有N个工作,M种机器,每种机器你可以租或者买过来. 每个工作包括若干道工序,每道工序需要某种机器来完成,你可以通过购买或租用机器来完成. 现在给出这些参数,求最大利润 关于建图和思路 刚开始看这道题的时候十分纠结,任务的做与不做,应当是典型的最小割取舍模型 然而买机器和租机器,又是常见的最小费用最大流模型的标志 进一步思考,对于每一对如下关系(任务)-(机器) 一共有三种处理方法: 1)任务不做 2)租用机器 3)购买机器 好像看出了点眉目,对于第一种

贪心法求树的最小支配集,最小点覆盖,最大独立集

定义: 最小支配集:对于图G = (V, E) 来说,最小支配集指的是从 V 中取尽量少的点组成一个集合, 使得 V 中剩余的点都与取出来的点有边相连.也就是说,设 V' 是图的一个支配集,则对于图中的任意一个顶点 u ,要么属于集合 V', 要么与 V' 中的顶点相邻. 在 V' 中除去任何元素后 V' 不再是支配集, 则支配集 V' 是极小支配集.称G 的所有支配集中顶点个数最少的支配集为最小支配集,最小支配集中的顶点个数称为支配数. 最小点覆盖:对于图G = (V, E) 来说,最小点覆盖

POJ 3281 Dining(最大流建图 &amp;&amp; ISAP &amp;&amp; 拆点)

题目链接:http://poj.org/problem?id=3281 努力练建图ing!!! 题意:有 N 头牛,有 F 种食物和 D 种饮料,每种食物或饮料只能供一头牛享用,且每头牛只享用一种食物和一种饮料. 第2行-第N+1行.是牛i 喜欢A种食物,B种饮料,及食物种类列表和饮料种类列表. 问最多能使几头牛同时享用到自己喜欢的食物和饮料.->最大流. 本题难点是建图: 思路:一般都是左边一个集合表示源点与供应相连,右边一个集合表示需求与汇点相连. 但是本题,牛作为需求仍然是一个群体,但是供

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

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

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

poj2226Muddy Fields 二分匹配之最小点覆盖

//给r*c的 field ,有的地方有水,用宽度为1,长度任意的木板将这些有水的地方, //遮住,木板可以相互叠加,木板不能遮住有草的地方 //可以每行中的连续的格子看成一个点xi,每一列中连续的格子看成一个点yj //将每一个有水的格子看成一条边连接对应的xi , yj //那么其最小点覆盖即为答案 #include<cstdio> #include<cstring> #include<iostream> using namespace std ; const in