Land of Farms HDU - 5556 二分图匹配

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

3
3 4
..3.
023.
.211
2 3
...
...
4 4
1111
1..1
1991
1111

Sample Output

Case #1: 4
Case #2: 3
Case #3: 1题意:一个N*M的矩阵,其中“.”代表空地,“0-9”代表古代建筑,我们如果选择了一个编号的古代建筑想要建立,那么对应就要将全部该编号的建筑建立起来,如果在空地上建筑,只建立当前点。问最多能够建立多少种建筑,并且每两种建筑之间没有公共边。这题我做的非常吃力。

冷静分析 先考虑没有任何建筑的情况,也就是两两不能相连,看有多少个建筑这个就是跑一边二分图最大匹配就出来了。知道这个之后,然后再思考建筑总共只有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 + 7;
 39 const int maxn = 3e6 + 10;
 40 const int INF = 0x3f3f3f3f;
 41 const LL INFLL = 0x3f3f3f3f3f3f3f3fLL;
 42 char a[15][15];
 43 int dx[4] = {0, 0, 1, -1};
 44 int dy[5] = {1, -1, 0, 0};
 45 int t, cas = 1, n, m, sum, ans, use[15], vis[15];
 46 int vis2[15][15], vis3[15][15], match[3000], vis4[3000];
 47 vector<int>mp[105];
 48 int Find ( int u ) {
 49     for ( int i = 0 ; i < mp[u].size(); i++ ) {
 50         int v = mp[u][i];
 51         if ( !vis4[v] ) {
 52             vis4[v] = 1;
 53             if ( match[v] == -1 || Find ( match[v] ) ) {
 54                 match[v] = u;
 55                 return 1;
 56             }
 57         }
 58     }
 59     return 0;
 60 }
 61 void solve() {
 62     mem ( vis2, 0 );
 63     for ( int i = 0 ; i < n ; i++ ) {
 64         for ( int j = 0 ; j < m ; j++ ) {
 65             if ( a[i][j] == ‘.‘ ) {
 66                 for ( int k = 0; k < 4 ; k++ ) {
 67                     int x = i + dx[k], y = j + dy[k];
 68                     if ( x >= 0 && x < n && y >= 0 && y < m && a[x][y] != ‘.‘ && vis[a[x][y] - ‘0‘] )  vis2[i][j] = 1;
 69                 }
 70             } else {
 71                 vis2[i][j] = 1;
 72                 for ( int k = 0; k < 4 ; k++ ) {
 73                     int x = i + dx[k], y = j + dy[k];
 74                     if ( x >= 0 && x < n && y >= 0 && y < m ) {
 75                         if ( vis[a[i][j] - ‘0‘] == 1 && vis[a[x][y] - ‘0‘] == 1 && a[i][j] != a[x][y] ) {
 76                             return ;
 77                         }
 78                     }
 79                 }
 80             }
 81         }
 82     }
 83     int num = 0;
 84     for ( int i = 0 ; i < n ; i++ )
 85         for ( int j = 0 ; j < m ; j++ )
 86             if ( !vis2[i][j] ) vis3[i][j] = ++num;
 87     for ( int i = 0 ; i <= n * m ; i++ ) mp[i].clear();
 88     for ( int i = 0 ; i < n ; i++ ) {
 89         for ( int j = 0 ; j < m ; j++ ) {
 90             if ( !vis2[i][j] ) {
 91                 for ( int k = 0 ; k < 4 ; k++ ) {
 92                     int x = i + dx[k], y = j + dy[k];
 93                     if ( x >= 0 && x < n && y >= 0 && y < m && !vis2[x][y] ) mp[vis3[i][j]].push_back ( vis3[x][y] );
 94                 }
 95             }
 96         }
 97     }
 98     int res = 0;
 99     mem ( match, -1 );
100     for ( int i = 1 ; i <= num ; i++ ) {
101         mem ( vis4, 0 );
102         if ( Find ( i ) ) res++;
103     }
104     int key = 0;
105     for ( int i = 0 ; i < sum ; i++ ) if ( vis[i] ) key++;
106   //  bug, fuck ( key ), fuck ( num ), fuck ( res );
107     ans = max ( ans, key + num - res / 2 );
108 }
109 void dfs ( int now ) {
110     if ( now == sum ) {
111         solve();
112         return ;
113     }
114     vis[now] = 1;
115     dfs ( now + 1 );
116     vis[now] = 0;
117     dfs ( now + 1 );
118 }
119 int main() {
120    // FIN;
121     sf ( t );
122     while ( t-- ) {
123         sum = 0;
124         mem ( use, -1 );
125         sff ( n, m );
126         for ( int i = 0 ; i < n ; i++ ) {
127             scanf ( "%s", a[i] );
128             for ( int j = 0 ; j < m ; j++ ) {
129                 if ( a[i][j] != ‘.‘ ) {
130                     if ( use[a[i][j] - ‘0‘] != -1 ) a[i][j] = use[a[i][j] - ‘0‘] + ‘0‘;
131                     else use[a[i][j] - ‘0‘] = sum++, a[i][j] = use[a[i][j] - ‘0‘] + ‘0‘;
132                 }
133             }
134         }
135         ans = 0;
136         dfs ( 0 );
137         printf ( "Case #%d: %d\n", cas++, ans );
138     }
139     return 0;
140 }

 

原文地址:https://www.cnblogs.com/qldabiaoge/p/9904231.html

时间: 2024-12-15 23:53:37

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

hdu 2063 二分图匹配

题意:一些女的和一些男的有好感,有好感的能一起坐过山车,问最多能组成多少对 hdu 11 页上少有的算法题,二分图匹配问题,匈牙利算法,对于每一个汉子,看和他有好感的妹子有没有配对了,没有配对过就可以成功配对,若已经配对过了,就看那个妹子所配对的汉子能不能再找个没有配对的妹子,如果可以就拆散当前配对重组配对,否则就不能拆:如果找完所有有好感的妹子仍然没能配对成功,那这个汉子就注定孤独一生了``` 1 #include<stdio.h> 2 #include<string.h> 3

hdu 1281 二分图匹配

题目:在保证尽量多的“车”的前提下,棋盘里有些格子是可以避开的,也就是说,不在这些格子上放车,也可以保证尽量多的“车”被放下.但是某些格子若不放子,就 无法保证放尽量多的“车”,这样的格子被称做重要点.Gardon想让小希算出有多少个这样的重要点,你能解决这个问题么? 二分图匹配居然还能这么用!!!脑洞大开啊!!! 思路:把棋盘的行x看成二分图左边的点,列y看成二分图右边的点,那么就把可以放车的位置看成是一条边,而二分图的最大匹配中x互不相同,y 互不相同,所以每个匹配都是不同行不同列,所以最大

hdu 4185 二分图匹配

题意用1*2的木板覆盖矩阵中的‘#’,(木板要覆盖的只能是‘#’),问最多能用几个木板覆盖 将#抽象为二分图的点,一个木板就是一个匹配,注意最后结果要除以2 Sample Input 1 6 ...... .##... .##... ....#. ....## ...... Sample Output Case 1: 3 1 #include<stdio.h> 2 #include<string.h> 3 const int MAXN=1000; 4 char map[610][6

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

Problem Description RPG girls今天和大家一起去游乐场玩,终于可以坐上梦寐以求的过山车了.可是,过山车的每一排只有两个座位,而且还有条不成文的规矩,就是每个女生必须找个个男生做partner和她同坐.但是,每个女孩都有各自的想法,举个例子把,Rabbit只愿意和XHD或PQK做partner,Grass只愿意和linle或LL做partner,PrincessSnow愿意和水域浪子或伪酷儿做partner.考虑到经费问题,boss刘决定只让找到partner的人去坐过山

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

最大独立集证明参考:https://blog.csdn.net/qq_34564984/article/details/52778763 最大独立集证明: 上图,我们用两个红色的点覆盖了所有边.我们证明的前提条件是已经达到最小覆盖. 即条件1.已经覆盖所有边,条件2.所用的点数最小 首先我们来证明蓝色点组成的是一个独立集:如果有两个蓝色点间有边相连,那么这条 边则没有被覆盖,则与条件1矛盾.因此是独立集. 再来证明这个独立集最大: 如果我们要再增加这个独立集中的点,则需要把某个红点变 成蓝点.而

HDU 1507 Uncle Tom&#39;s Inherited Land*(二分图匹配)

Uncle Tom's Inherited Land* Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 3339    Accepted Submission(s): 1394Special Judge Problem Description Your old uncle Tom inherited a piece of land fro

杭电HDU ACM Uncle Tom&#39;s Inherited Land*(二分图匹配 建模)

Uncle Tom's Inherited Land* Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 2496    Accepted Submission(s): 1028 Special Judge Problem Description Your old uncle Tom inherited a piece of land f

hdu 5556 Land of Farms 最大团+暴力

Land of Farms Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 539    Accepted Submission(s): 177 Problem Description Farmer John and his brothers have found a new land. They are so excited and d

HDU_1507_Uncle Tom&#39;s Inherited Land*(二分图匹配)

Uncle Tom's Inherited Land* Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 2208    Accepted Submission(s): 913 Special Judge Problem Description Your old uncle Tom inherited a piece of land fr