Source: HDU 3360 National Treasures
Question: If a [I] [j]! =-1 convert it to binary. a maximum of 12 digits represent the 12 positions in the graph of the question. If the corresponding position is 1, a guard can be placed there to hold a [I] [j]. location.
Train of Thought: overwrite the obviously dead minimum point to create an odd-even matching Graph
#include <cstdio>#include <cstring>#include <vector>using namespace std;const int maxn = 55;int vis[maxn*maxn];int y[maxn*maxn];vector <int> G[maxn*maxn];int n, m;int a[maxn][maxn];int dir[12][2] = {-1, -2, -2, -1, -2, 1, -1, 2, 1, 2, 2, 1, 2, -1, 1, -2, -1, 0, 0, 1, 1, 0, 0, -1};bool dfs(int u){ for(int i = 0; i < G[u].size(); i++) { int v = G[u][i]; if(vis[v]) continue; vis[v] = true; if(y[v] == -1 || dfs(y[v])) { y[v] = u; return true; } } return false;}int match(){ int ans = 0; memset(y, -1, sizeof(y)); for(int i = 0; i < n; i++) { for(int j = 0; j < m; j++) { if((i+j)%2){memset(vis, 0, sizeof(vis)); if(dfs(i*m+j)) ans++;} } } return ans;}int main(){int cas = 1;while(scanf("%d %d", &n, &m) && (n||m)){for(int i = 0; i < n; i++)for(int j = 0; j < m; j++)scanf("%d", &a[i][j]);for(int i = 0; i < n*m; i++)G[i].clear();for(int i = 0; i < n; i++){for(int j = 0; j < m; j++){int x = a[i][j];if(x == -1)continue;for(int k = 0; k < 12; k++, x >>= 1){if(!x)break;if(!(x&1))continue;int xx = i + dir[k][0];int yy = j + dir[k][1];if(xx < 0 || xx >= n || yy < 0 || yy >= m)continue;if(a[xx][yy] == -1)continue;if((i+j)%2)G[i*m+j].push_back(xx*m+yy);elseG[xx*m+yy].push_back(i*m+j);}}}printf("%d. %d\n", cas++, match());} return 0;}