思路:要安放一下类似雷达之类的东西,相邻的一个点会被覆盖,但是,只能覆盖一个,不管是东西南北,那么另外一个被覆盖的点就不用在安放雷达了,求最少的安放雷达的数目;显然就是最小边覆盖问题;
对每个坐标表定一个固定的数字,然后根据题意建图;与这题一样的还有lightoj1152。
题目链接
/***************************************** Author :Crazy_AC(JamesQi) Time :2015 File Name : *****************************************/ // #pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <algorithm> #include <iomanip> #include <sstream> #include <string> #include <stack> #include <queue> #include <deque> #include <vector> #include <map> #include <set> #include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> #include <limits.h> using namespace std; #define MEM(a,b) memset(a,b,sizeof a) typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> ii; const int inf = 1 << 30; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; char gg[50][50]; int link[50 * 50]; vector<int> G[50 * 50]; int dx[] = {-1,0,1,0}; int dy[] = {0,-1,0,1}; bool vis[50 * 50]; int n,m; bool dfs(int u){ for (int i = 0;i < G[u].size();i++){ int v = G[u][i]; if (!vis[v]){ vis[v] = true; if (link[v] == -1 || dfs(link[v])){ link[v] = u; return true; } } } return false; } int Hungary(){ MEM(link, -1); int ret = 0; for (int i = 1;i <= n * m;i++){ MEM(vis, false); if (dfs(i)) ret++; } return ret; } int main() { // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); int T; cin >> T; while(T--){ cin >> n >> m; for (int i = 1;i <= n * m;i++) G[i].clear(); for (int i = 1;i <= n;i++){ scanf("%s",gg[i] + 1); } int cnt = 0; for (int i = 1;i <= n;i++){ for (int j = 1;j <= m;j++){ if (gg[i][j] == '*'){ cnt++; for (int k = 0;k < 4;k++){ int nx = i + dx[k]; int ny = j + dy[k]; if (nx < 1 || nx > n || ny < 1 || ny > m) continue; if (gg[nx][ny] == '*') G[(i - 1) * m + j].push_back((nx - 1) * m + ny); } } } } printf("%d\n",cnt - Hungary() / 2); } return 0; }
// #pragma comment(linker, "/STACK:1024000000,1024000000") //Light_OJ 1152 #include <iostream> #include <algorithm> #include <iomanip> #include <sstream> #include <string> #include <stack> #include <queue> #include <deque> #include <vector> #include <map> #include <set> #include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> #include <limits.h> // #define DEBUG #ifdef DEBUG #define debug(...) printf( __VA_ARGS__ ) #else #define debug(...) #endif #define MEM(x,y) memset(x, y,sizeof x) using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> ii; const int inf = 1 << 30; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; int n, m; const int maxn = 30; char s[maxn][maxn]; int link[maxn*maxn]; bool vis[maxn*maxn]; vector<int> G[maxn*maxn]; bool Search(int u){ for (int i = 0;i < G[u].size();++i){ int v = G[u][i]; if (vis[v]) continue; vis[v] = true; if (link[v] == -1 || Search(link[v])){ link[v] = u; return true; } } return false; } int Hungary(){ int ans = 0; memset(link, -1,sizeof link); for (int i = 1;i <= n * m;++i){ memset(vis, false,sizeof vis); if (Search(i)) ans++; } return ans; } int dx[] = {-1,0,1,0}; int dy[] = {0,-1,0,1}; int main() { // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); int t, icase = 0; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); for (int i = 1;i <= n;++i) scanf("%s",s[i] + 1); for (int i = 0;i <= n * m;++i) G[i].clear(); int cnt = 0; for (int i = 1;i <= n;++i){ for (int j = 1;j <= m;++j){ if (s[i][j] == '*'){ cnt++; for (int k = 0;k < 4;++k){ int nx = i + dx[k]; int ny = j + dy[k]; if (nx < 1 || nx > n || ny < 1 || ny > m) continue; if (s[nx][ny] == '*'){ G[(i-1)*m+j].push_back((nx-1)*m+ny); } } } } } printf("Case %d: %d\n", ++icase, cnt - Hungary()/2); } return 0; }