思路:这题是一个经典的二分图匹配;图中‘X’表示wall,‘.’表示空地可以放置blockhouse,同一条可达线(中间没有wall)上只能有一个blockhouse,显然这样的话这一段空间就只能放一个了,行与列都是如此;所以就可以对这种段进行缩点,然后进行二分匹配就好了;
/***************************************** 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) #define pk push_back template<class T> inline T Get_Max(const T&a,const T&b){return a < b?b:a;} template<class T> inline T Get_Min(const T&a,const T&b){return a < b?a:b;} typedef long long ll; typedef pair<int,int> ii; const int inf = 1 << 30; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; const int maxn = 1010; int gg[maxn][maxn]; char str_map[maxn][maxn]; int col[maxn][maxn]; int row[maxn][maxn]; int mark[maxn]; int link[maxn]; int uN,vN; bool Search_P(int u){ for (int i = 0;i < vN;i++){ if (!mark[i] && gg[u][i]){ mark[i] = 1; if (link[i] == -1 || Search_P(link[i])){ link[i] = u; return true; } } } return false; } inline int Hungary(){ int ret = 0; MEM(link, -1); for (int i = 0;i < uN;i++){ MEM(mark, 0); if (Search_P(i)) ret++; } return ret; } int main() { // ios::sync_with_stdio(false); // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); int n; while(~scanf("%d%*c",&n) && n){ for (int i = 0;i < n;i++){ for (int j = 0;j < n;j++) str_map[i][j] = getchar(); getchar(); } uN = vN = 0; MEM(row, -1); MEM(col, -1); for (int i = 0;i < n;++i){ for (int j = 0;j < n;++j){ if (str_map[i][j] == '.' && row[i][j] == -1){ for (int k = j;k < n && str_map[i][k] == '.';k++) row[i][k] = uN; uN++; } if (str_map[i][j] == '.' && col[i][j] == -1){ for (int k = i;k < n && str_map[k][j] == '.';k++) col[k][j] = vN; vN++; } } } MEM(gg, 0); for (int i = 0;i < n;++i){ for (int j = 0;j < n;++j){ if (str_map[i][j] == '.') gg[row[i][j]][col[i][j]] = 1; } } printf("%d\n", Hungary()); } return 0; }
/***************************************** 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) #define pk push_back template<class T> inline T Get_Max(const T&a,const T&b){return a < b?b:a;} template<class T> inline T Get_Min(const T&a,const T&b){return a < b?a:b;} typedef long long ll; typedef pair<int,int> ii; const int inf = 1 << 30; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; const int maxn = 1010; char s[maxn][maxn]; int gx[maxn][maxn]; int gy[maxn][maxn]; int uN,vN; vector<int> G[maxn]; int dx[maxn],dy[maxn]; int Mx[maxn],My[maxn]; bool vis[maxn]; int dis; bool SearchP(){ queue<int> que; MEM(dx, -1); MEM(dy, -1); for (int i = 1;i <= uN;i++){ if (Mx[i] == -1){ dx[i] = 0; que.push(i); } } dis = INF; while(!que.empty()){ int u = que.front(); que.pop(); if (dx[u] > dis) break; for (int i = 0;i < G[u].size();i++){ int v = G[u][i]; if (dy[v] == -1){ dy[v] = dx[u] + 1; if (My[v] == -1) dis = dy[v]; else{ dx[My[v]] = dy[v] + 1; que.push(My[v]); } } } } return dis != INF; } bool dfs(int u){ for (int i = 0;i < G[u].size();i++){ int v = G[u][i]; if (!vis[v] && dy[v] == dx[u] + 1){ vis[v] = true; if (My[v] != -1 && dis == dy[v]) continue; if (My[v] == -1 || dfs(My[v])){ My[v] = u; Mx[u] = v; return true; } } } return false; } inline int Hopcroft_Karp(){ int ret = 0; MEM(Mx, -1); MEM(My, -1); while(SearchP()){ MEM(vis, false); for (int i = 1;i <= uN;i++){ if (Mx[i] == -1 && dfs(i)) ret++; } } return ret; } int main() { // ios::sync_with_stdio(false); // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); int n; while(~scanf("%d",&n) && n){ uN = vN = 0; for (int i = 1;i <= n;i++){ scanf("%s",s[i] + 1); } MEM(gx, -1);MEM(gy, -1); for (int i = 1;i <= n;i++){ for (int k = 1;k <= n;k++){ if (s[i][k] == '.' && gx[i][k] == -1){ uN++; for (int j = k;j <= n;j++){ if (s[i][j] == '.') gx[i][j] = uN; else break; } } } for (int k = 1;k <= n;k++){ if (s[k][i] == '.' && gy[k][i] == -1){ vN++; for (int j = k;j <= n;j++){ if (s[j][i] == '.') gy[j][i] = vN; else break; } } } } // cout << "uN = " << uN << endl; // cout << "vN = " << vN << endl; for (int i = 1;i <= uN;i++)G[i].clear(); for (int i = 1;i <= vN;i++)G[i].clear(); for (int i = 1;i <= n;i++){ for (int j = 1;j <= n;j++){ if (s[i][j] == '.'){ G[gx[i][j]].push_back(gy[i][j]); // G[gy[i][j]].push_back(gx[i][j]); } } } int ans = Hopcroft_Karp(); printf("%d\n",ans); } return 0; }