题目链接:

https://vjudge.net/problem/POJ-2226

题目大意:

用宽度为1长度不限的木板将水洼‘*’盖住而不盖住草‘.'

Sample Input

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

Sample Output

4

解题思路:

这道题的构图方法十分巧妙,如果有连续的水洼,假设是横排的,那么这几个连续的水洼可以拿一个板子来覆盖,同样,如果竖排也有连续的水洼,那么也可以拿一个板子来覆盖。这样,当一个水洼既可以拿横着的板子,也可以拿竖着的板子覆盖时,就是相交了。那么这个交线就代表了一个水洼,它既可以被横着盖,也可以被竖着盖。现在我们把所有横排的水洼作为1个水洼需要1个木板,竖着的也同理。

有两种覆盖的方法,一种为横着盖一种为竖着盖覆盖后可转化为下图形式

横着盖:(图中数字表示用的是第几块木板)
1.2.
.333
444.
. . 5.
将这些点加入到X序列中
竖着盖:
1.2.
.324
532.
. . 2.
将这些点加入到Y序列中
将图中水洼进行编号一共有九个水洼
1.2.
.345
678.
. . 9.
9号水洼(5, 2)表示九号水洼可由横着的5号木板覆盖也可以由竖着的2号木板覆盖,5号木板和2号木板之间就有一条线

这样就组成一个二分图,最后求最小的顶点覆盖。就是等于保证每个泥地都被横着的木板或者竖着的木板覆盖了。
 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<vector>
 5 using namespace std;
 6 const int maxn = 2500 + 10;
 7
 8 int cx[maxn], cy[maxn];
 9 bool vis[maxn];
10 vector<int>G[maxn];
11 int x, y;
12 //x表示二分图X部的点数
13 //y表示二分图Y部的点数
14 bool dfs(int u)
15 {
16     for(int i = 0; i < G[u].size(); i++)
17     {
18         int v = G[u][i];
19         if(!vis[v])//如果该点还没进入增广路
20         {
21             vis[v] = 1;//加入增广路
22             if(cy[v] == -1 || dfs(cy[v]))
23             {
24                 cx[u] = v;
25                 cy[v] = u;
26                 return 1;
27             }
28         }
29     }
30     return 0;
31 }
32
33 int maxmatch()
34 {
35     int ans = 0;
36     memset(cx, -1, sizeof(cx));
37     memset(cy, -1, sizeof(cy));
38     for(int i = 1; i <= x; i++)
39     {
40         if(cx[i] == -1)
41         {
42             memset(vis, 0, sizeof(vis));
43             ans += dfs(i);
44         }
45     }
46     return ans;
47 }
48 char Map[55][55];
49 int cnt[55][55], n, m;
50 void Build()//建图巧妙
51 {
52     int a[55][55], b[55][55];
53     memset(a, 0, sizeof(a));
54     memset(b, 0, sizeof(b));
55     //木板横着放
56     x = 0, y = 0;
57     for(int i = 0; i < n; i++)
58     {
59         for(int j = 0; j < m; j++)
60         {
61             if(Map[i][j] == '*')
62             {
63                 if(Map[i][j - 1] == '*')
64                     a[i][j] = a[i][j - 1];
65                 else a[i][j] = ++x;
66             }
67         }
68     }
69     //木板竖着放
70     for(int j = 0; j < m; j++)
71     {
72         for(int i = 0; i < n; i++)
73         {
74             if(Map[i][j] == '*')
75             {
76                 if(Map[i - 1][j] == '*')
77                     b[i][j] = b[i - 1][j];
78                 else b[i][j] = ++y;
79                 //cout<<a[i][j]<<" "<<b[i][j]<<endl;
80                 //建边
81                 G[a[i][j]].push_back(b[i][j]);
82             }
83         }
84     }
85 }
86 int main()
87 {
88     cin >> n >> m;
89     for(int i = 0; i < n; i++)
90     {
91         cin >> Map[i];
92     }
93     Build();
94     cout<<maxmatch()<<endl;
95     return 0;
96 }

转载于:https://www.cnblogs.com/fzl194/p/8838654.html

POJ-2226 Muddy Fields---二分图匹配+巧妙构图相关推荐

  1. POJ - 2226 Muddy Fields(最小点覆盖-二分图最大匹配)

    题目链接:点击查看 题目大意:给出一个n*m的地图,地图中'*'代表泥地,'.'代表空地,现在我们有两种木板,一种可以覆盖一行中的任意长度,我们成为行木板,另一种可以覆盖一列中的任意长度,我们成为列木 ...

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

    1 /* 2 题意:用木板盖住泥泞的地方,不能盖住草.木板任意长!可以重叠覆盖! '*'表示泥泞的地方,'.'表示草! 3 思路: 4 首先让我们回忆一下HDU 2119 Matrix这一道题,一个矩 ...

  3. poj 2226 Muddy Fields 最小顶点覆盖

    题目链接:http://poj.org/problem?id=2226 这道题跟上一道很相似不同之处在于这里不是整行或者整列的删,而是连续的几个可以一起删,不连的不能删,这就要对原图进行处理,对原有的 ...

  4. POJ 2226 Muddy Fields 最小点覆盖+加建图(好题)

    题目链接 题目一看就是最小点覆盖,这道题与POJ - 3041 算是一类题,但是3041算是一道十分裸的,因为删除的是整行或者整列,所以图其实是现成的,但是本题的难点就在如何建图. 思路:首先还是尽量 ...

  5. POJ 2226 Muddy Fields(最小点覆盖)题解

    题意:一片r*c的地,有些地方是泥地,需要铺地板.这些地板宽1,长无限,但只能铺在泥地上不能压到其他地方,问你铺满所有泥地最少几块 思路:我们把一行中连续的泥地看成整体,并把所有横的整体里的点编成一个 ...

  6. POJ 2724 Purifying Machine (二分图匹配)

    题意 给定m个长度为n的01串(*既表示0 or 1.如*01表示001和101).现在要把这些串都删除掉,删除的方法是:①一次删除任意指定的一个:②如果有两个串仅有一个字符不同,则可以同时删除这两个 ...

  7. poj2226Muddy Fields——二分图匹配

    题目:http://poj.org/problem?id=2226 把行连通块作为左部点,列连通块作为右部点,行列连通块有相交的格子就连边: 则问题转化为求最小点覆盖,即最大匹配. 代码如下: #in ...

  8. POJ 1325 Machine Schedule[二分图匹配*最小点覆盖]

    题意: 两台机器,有 k 个工作,每个工作可以在 a 机器的 P 模式或在 b 机器的 q 模式下解决,两台机器初始状态为 0 模式,每台机器没变换一次模都要重启一次, 问至少重启多少次可以完成所有工 ...

  9. POJ2226 Muddy Fields 二分图求最小覆盖点

    这题的关键在于建图,这题当中,因为要求木板覆盖泥坑,但又不能覆盖草,所以不能简单的行和列对应建图,我们要对行中泥坑进行编号,连一起的编同样的号,同样的对列中连一起的泥坑进行编号,如果行列编号的一块泥坑 ...

最新文章

  1. Python脚本如何生成Windows可执行文件.exe
  2. ASP.NET Core必备笔试题(含答案)
  3. How is default text type determined for Account view
  4. 美学设计评价_死亡的孩子无法使用的设计美学
  5. 发了篇paper,双非二本的她直博浙大
  6. Highchart series一次只显示一条
  7. 数据治理与元模型_开放项目的治理模型如何演变
  8. android emulator虚拟设备之qemu pipe分析(三)
  9. FragmentSharedFabTransition
  10. 基于SPRINGBOOT高速交警日常办公管理系统
  11. JavaScript实现汉字转拼音功能
  12. 美国通胀率“破9”创40年新高 加密步履蹒跚?全球屏住呼吸等待美国下一步动作
  13. x平方检验计算_x2检验或卡方检验和校正卡方检验计算
  14. sox处理mp3_SOX 音频处理
  15. Dbeaver链接hive和impala
  16. 面向对象和面向过程的区别通俗理解
  17. 【无用之书】侦探小说的二十条规则
  18. 一些实用的cmd命令,让你变得很牛X
  19. Android Manifest详解
  20. 榛果 美团 登录 爬虫 requests session

热门文章

  1. 2021年起重机械指挥考试题及起重机械指挥模拟考试题
  2. 百度OCR(文字识别)服务使用入坑指南
  3. 因为1克能量,我发现了蚂蚁森林背后的灰色产业
  4. 【中间件技术】第二部分 CORBA规范与中间件(1) CORBA基本原理
  5. 如何做好商业画册设计
  6. 影响NETGEAR路由器的0-Day:KCodes NetUSB两个安全漏洞披露(CVE-2019-5016/5017)
  7. 一口气说完MR、Storm、Spark、SparkStreaming和Flink
  8. [转帖]华为的“大海思”与“小海思”
  9. u-boot启动过程分析(一)
  10. 无线降噪耳机怎么选?佩戴舒适的降噪耳机推荐