本文共 5829 字,大约阅读时间需要 19 分钟。
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
33 4..3.023..2112 3......4 411111..119911111
Sample Output
Case #1: 4Case #2: 3Case #3: 1 题意: 一个N*M的矩阵,其中“.”代表空地,“0-9”代表古代建筑,我们如果选择了一个编号的古代建筑想要建立, 那么对应就要将全部该编号的建筑建立起来,如果在空地上建筑,只建立当前点。问最多能够建立多少种建筑, 并且每两种建筑之间没有公共边。 这题我做的非常吃力。 冷静分析 先考虑没有任何建筑的情况,也就是两两不能相连,看有多少个建筑 这个就是跑一边二分图最大匹配就出来了。 知道这个之后,然后再思考建筑总共只有10种,所以枚举一下有哪几种建筑存在, 暴搜每一种合法的情况。 细节一定要处理好,选定的建筑周围的空白格子根据题意要抠出来。选的的建筑不能有相连; ans=扣点后的空白的数目-扣点后的空白的数目的最大匹配+选择的建筑的数目
1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #include 9 #include 10 #include 11 #include 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" = "< < = 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 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