Land of Farms HDU - 5556 二分圖匹配
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
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 }View Code