Poj 3020 antenna placement
Question Link
Question: Given a map, the place of '*' should be covered. Each time we can use a rectangle of 1X2 to cover the map, we can use at least a few to cover the map.
Idea: bipartite graph matching to find the Maximum Independent Set, adjacent * edge, and then find the maximum independent set.
Depending on the data range, you can also use the outline DP.
Code:
#include <cstdio>#include <cstring>#include <vector>#include <algorithm>using namespace std;const int N = 45;const int d[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};int t, h, w, cnt, to[N][N];char str[N][N];vector<int> g[N * N];int left[N * N], vis[N * N];bool dfs(int u) {for (int i = 0; i < g[u].size(); i++) {int v = g[u][i];if (vis[v]) continue;vis[v] = 1;if (left[v] == -1 || dfs(left[v])) {left[v] = u;return true;}}return false;}int hungary() {int ans = 0;memset(left, -1, sizeof(left));for (int i = 0; i < cnt; i++) {memset(vis, 0, sizeof(vis));if (dfs(i)) ans++;}return ans;}int main() {scanf("%d", &t);while (t--) {cnt = 0;scanf("%d%d", &h, &w);for (int i = 0; i < h; i++) {scanf("%s", str[i]);for (int j = 0; j < w; j++) {if (str[i][j] == '*') {g[cnt].clear();to[i][j] = cnt++;}}}for (int i = 0; i < h; i++) {for (int j = 0; j < w; j++) {if (str[i][j] == 'o') continue;for (int k = 0; k < 4; k++) {int x = i + d[k][0];int y = j + d[k][1];if (x < 0 || x >= h || y < 0 || y >= w || str[x][y] == 'o') continue;g[to[i][j]].push_back(to[x][y]);}}}printf("%d\n", cnt - hungary() / 2);}return 0;}
Poj 3020 antenna placement (Bipartite Graph Matching)