Farmer John and his brothers have found a new land. They are so excited and decide to build new farms on the land. The land is a rectangle and consists of N×MN×Mgrids. A farm consists of one or more connected grids. Two grids are adjacent if they share a common border, i.e. their Manhattan distance is exactly 1. In a farm, two grids are considered connected if there exist a series of adjacent grids, which also belong to that farm, between them.

Farmer John wants to build as many farms as possible on the new land. It is required that any two farms should not be adjacent. Otherwise, sheep from different farms would fight on the border. This should be an easy task until several ancient farms are discovered.

Each of the ancient farms also consists of one or more connected grids. Due to the respect to the ancient farmers, Farmer John do not want to divide any ancient farm. If a grid from an ancient farm is selected in a new farm, other grids from the ancient farm should also be selected in the new farm. Note that the ancient farms may be adjacent, because ancient sheep do not fight each other.

The problem is a little complicated now. Can you help Farmer John to find a plan with the maximum number of farms? 

InputThe first line of input contains a number TT indicating the number of test cases (T≤200T≤200).

Each test case starts with a line containing two integers NN and MM, indicating the size of the land. Each of the following NN lines contains MM characters, describing the map of the land (1≤N,M≤101≤N,M≤10). A grid of an ancient farm is indicated by a single digit (0-9). Grids with the same digit belong to the same ancient farm. Other grids are denoted with a single character “ .”. It is guaranteed that all test cases are valid. 
OutputFor each test case, output a single line consisting of “ Case #X: Y”. XX is the test case number starting from 1. YY is the maximum number of new farms.Sample Input

  1. 3
  2. 3 4
  3. ..3.
  4. 023.
  5. .211
  6. 2 3
  7. ...
  8. ...
  9. 4 4
  10. 1111
  11. 1..1
  12. 1991
  13. 1111

Sample Output

  1. Case #1: 4
  2. Case #2: 3
  3. Case #3: 1
    题意:
    一个N*M的矩阵,其中“.”代表空地,“0-9”代表古代建筑,我们如果选择了一个编号的古代建筑想要建立,
    那么对应就要将全部该编号的建筑建立起来,如果在空地上建筑,只建立当前点。问最多能够建立多少种建筑,
    并且每两种建筑之间没有公共边。
    这题我做的非常吃力。
  4.  
  5. 冷静分析 先考虑没有任何建筑的情况,也就是两两不能相连,看有多少个建筑
    这个就是跑一边二分图最大匹配就出来了。
    知道这个之后,然后再思考建筑总共只有10种,所以枚举一下有哪几种建筑存在,
    暴搜每一种合法的情况。
    细节一定要处理好,选定的建筑周围的空白格子根据题意要抠出来。选的的建筑不能有相连;
    ans=扣点后的空白的数目-扣点后的空白的数目的最大匹配+选择的建筑的数目
  1. #include <cstdio>
  2. #include <cstring>
  3. #include <queue>
  4. #include <cmath>
  5. #include <algorithm>
  6. #include <set>
  7. #include <iostream>
  8. #include <map>
  9. #include <stack>
  10. #include <string>
  11. #include <vector>
  12. #define pi acos(-1.0)
  13. #define eps 1e-6
  14. #define fi first
  15. #define se second
  16. #define rtl rt<<1
  17. #define rtr rt<<1|1
  18. #define bug printf("******\n")
  19. #define mem(a,b) memset(a,b,sizeof(a))
  20. #define name2str(x) #x
  21. #define fuck(x) cout<<#x" = "<<x<<endl
  22. #define f(a) a*a
  23. #define sf(n) scanf("%d", &n)
  24. #define sff(a,b) scanf("%d %d", &a, &b)
  25. #define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
  26. #define sffff(a,b,c,d) scanf("%d %d %d %d", &a, &b, &c, &d)
  27. #define pf printf
  28. #define FRE(i,a,b) for(i = a; i <= b; i++)
  29. #define FREE(i,a,b) for(i = a; i >= b; i--)
  30. #define FRL(i,a,b) for(i = a; i < b; i++)+
  31. #define FRLL(i,a,b) for(i = a; i > b; i--)
  32. #define FIN freopen("data.txt","r",stdin)
  33. #define gcd(a,b) __gcd(a,b)
  34. #define lowbit(x) x&-x
  35. using namespace std;
  36. typedef long long LL;
  37. typedef unsigned long long ULL;
  38. const int mod = 1e9 + ;
  39. const int maxn = 3e6 + ;
  40. const int INF = 0x3f3f3f3f;
  41. const LL INFLL = 0x3f3f3f3f3f3f3f3fLL;
  42. char a[][];
  43. int dx[] = {, , , -};
  44. int dy[] = {, -, , };
  45. int t, cas = , n, m, sum, ans, use[], vis[];
  46. int vis2[][], vis3[][], match[], vis4[];
  47. vector<int>mp[];
  48. int Find ( int u ) {
  49. for ( int i = ; i < mp[u].size(); i++ ) {
  50. int v = mp[u][i];
  51. if ( !vis4[v] ) {
  52. vis4[v] = ;
  53. if ( match[v] == - || Find ( match[v] ) ) {
  54. match[v] = u;
  55. return ;
  56. }
  57. }
  58. }
  59. return ;
  60. }
  61. void solve() {
  62. mem ( vis2, );
  63. for ( int i = ; i < n ; i++ ) {
  64. for ( int j = ; j < m ; j++ ) {
  65. if ( a[i][j] == '.' ) {
  66. for ( int k = ; k < ; k++ ) {
  67. int x = i + dx[k], y = j + dy[k];
  68. if ( x >= && x < n && y >= && y < m && a[x][y] != '.' && vis[a[x][y] - ''] ) vis2[i][j] = ;
  69. }
  70. } else {
  71. vis2[i][j] = ;
  72. for ( int k = ; k < ; k++ ) {
  73. int x = i + dx[k], y = j + dy[k];
  74. if ( x >= && x < n && y >= && y < m ) {
  75. if ( vis[a[i][j] - ''] == && vis[a[x][y] - ''] == && a[i][j] != a[x][y] ) {
  76. return ;
  77. }
  78. }
  79. }
  80. }
  81. }
  82. }
  83. int num = ;
  84. for ( int i = ; i < n ; i++ )
  85. for ( int j = ; j < m ; j++ )
  86. if ( !vis2[i][j] ) vis3[i][j] = ++num;
  87. for ( int i = ; i <= n * m ; i++ ) mp[i].clear();
  88. for ( int i = ; i < n ; i++ ) {
  89. for ( int j = ; j < m ; j++ ) {
  90. if ( !vis2[i][j] ) {
  91. for ( int k = ; k < ; k++ ) {
  92. int x = i + dx[k], y = j + dy[k];
  93. if ( x >= && x < n && y >= && y < m && !vis2[x][y] ) mp[vis3[i][j]].push_back ( vis3[x][y] );
  94. }
  95. }
  96. }
  97. }
  98. int res = ;
  99. mem ( match, - );
  100. for ( int i = ; i <= num ; i++ ) {
  101. mem ( vis4, );
  102. if ( Find ( i ) ) res++;
  103. }
  104. int key = ;
  105. for ( int i = ; i < sum ; i++ ) if ( vis[i] ) key++;
  106. // bug, fuck ( key ), fuck ( num ), fuck ( res );
  107. ans = max ( ans, key + num - res / );
  108. }
  109. void dfs ( int now ) {
  110. if ( now == sum ) {
  111. solve();
  112. return ;
  113. }
  114. vis[now] = ;
  115. dfs ( now + );
  116. vis[now] = ;
  117. dfs ( now + );
  118. }
  119. int main() {
  120. // FIN;
  121. sf ( t );
  122. while ( t-- ) {
  123. sum = ;
  124. mem ( use, - );
  125. sff ( n, m );
  126. for ( int i = ; i < n ; i++ ) {
  127. scanf ( "%s", a[i] );
  128. for ( int j = ; j < m ; j++ ) {
  129. if ( a[i][j] != '.' ) {
  130. if ( use[a[i][j] - ''] != - ) a[i][j] = use[a[i][j] - ''] + '';
  131. else use[a[i][j] - ''] = sum++, a[i][j] = use[a[i][j] - ''] + '';
  132. }
  133. }
  134. }
  135. ans = ;
  136. dfs ( );
  137. printf ( "Case #%d: %d\n", cas++, ans );
  138. }
  139. return ;
  140. }
  1.  

Land of Farms HDU - 5556 二分图匹配的更多相关文章

  1. hdu 2063 二分图匹配

    题意:一些女的和一些男的有好感,有好感的能一起坐过山车,问最多能组成多少对 hdu 11 页上少有的算法题,二分图匹配问题,匈牙利算法,对于每一个汉子,看和他有好感的妹子有没有配对了,没有配对过就可以 ...

  2. hdu 1281 二分图匹配

    题目:在保证尽量多的“车”的前提下,棋盘里有些格子是可以避开的,也就是说,不在这些格子上放车,也可以保证尽量多的“车”被放下.但是某些格子若不放子,就 无法保证放尽量多的“车”,这样的格子被称做重要点 ...

  3. hdu 1507(二分图匹配)

    Uncle Tom's Inherited Land* Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (J ...

  4. hdu 4185 二分图匹配

    题意用1*2的木板覆盖矩阵中的‘#’,(木板要覆盖的只能是‘#’),问最多能用几个木板覆盖 将#抽象为二分图的点,一个木板就是一个匹配,注意最后结果要除以2 Sample Input 1 6 .... ...

  5. 过山车 HDU 2063 (二分图匹配裸题)

    Problem Description RPG girls今天和大家一起去游乐场玩,终于可以坐上梦寐以求的过山车了.可是,过山车的每一排只有两个座位,而且还有条不成文的规矩,就是每个女生必须找个个男生 ...

  6. Fire Net HDU - 1045 (二分图匹配)

    题意: 给出一张图,图中'X'表示wall,'.'表示空地,可以放置blockhouse同一条直线上只能有一个blockhouse,除非有wall 隔开,问在给出的图中最多能放置多少个blockhou ...

  7. Girls and Boys HDU - 1068 二分图匹配(匈牙利)+最大独立集证明

    最大独立集证明参考:https://blog.csdn.net/qq_34564984/article/details/52778763 最大独立集证明: 上图,我们用两个红色的点覆盖了所有边.我们证 ...

  8. HDU 1507 Uncle Tom's Inherited Land*(二分图匹配)

    Uncle Tom's Inherited Land* Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (J ...

  9. hdu 5556 Land of Farms 最大团+暴力

    Land of Farms Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tot ...

随机推荐

  1. 【坚持】Selenium+Python学习之从读懂代码开始 DAY3

    2018/05/15 [来源:菜鸟教程](http://www.runoob.com/python3/python3-examples.html) #No.1 list = [1, 2, 3, 4] ...

  2. Atom 插件 Sync Settings 备份与恢复

    当使用 Atom IDEA.随着使用的越来越多,安装的插件也越来越多,一旦电脑重装后需要复原开发环境,这将是一件比较头疼的事.「Sync Settings」插件可以帮助我们解决这个问题. 操作流程 安 ...

  3. Linux系统网络安装——基于pxe+dhcp+nfs+tftp+kickstart

    原文发表于:2010-09-05 转载至cu于:2012-07-21 一.原理简介 PXE(preboot execute environment)工作于Client/Server的网络模式,支持工作 ...

  4. C语言—单链表

    单链表操作:读取,插入和删除 #include "stdafx.h" #include <string.h> #include <stdio.h> #inc ...

  5. Druid Monitor小记

    继上篇DruidDataSource源码分析之后 , 公司又要求做一个Druid的数据库监控 , 以及spring监控 , 研究一小时 , 总结出了一点经验 , 特此贴出来分享一下 一 . 利用Dru ...

  6. GitLab 搭建与使用

    操作系统:Centos 7 环境:VM虚拟机 0x00:这里说下VM 虚拟机的配置 然后选择NAT模式 接下来配置网络 cd /etc/sysconfig/network-scripts/ 编辑:vi ...

  7. 20135208 JAVA第四次实验

    课程:Java程序与设计     班级:1352 姓名:贺邦 小组成员: 20135212池彬宁 20135208贺邦 学号:20135208 成绩:             指导教师:娄嘉鹏     ...

  8. c++第三次作业

    GitHub地址 https://github.com/ronghuijun/3Elevators-scheduling 实现过程 一开始打算分成三个类来写的 因为想到电梯的功能不太一样 一个只能上1 ...

  9. iOS- 如何建立索引实现本地文本搜索引擎,允许容错搜索?

    1.前言 实现一个本地搜索引擎,允许容错搜索,也就是搜索结果不需要和搜索的关键字完全精准匹配.比如,搜索”eric wang“,搜索结果可以包括Erica Watts等等.搜索效率十分高. 这里我们需 ...

  10. 第五周PSP &进度条

    团队项目PSP 一:表格     C类型 C内容 S开始时间 E结束时间 I时间间隔 T净时间(mins) 预计花费时间(mins) 讨论 讨论用户界面 9:27 10:42 18 57 60 分析与 ...