二分图匹配 建图的经典之作
#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <vector>
#include <stack>
#include <deque>
#include <queue>
#include <bitset>
#include <list>
#include <map>
#include <set>
#include <iterator>
#include <algorithm>
#include <functional>
#include <utility>
#include <sstream>
#include <climits>
#include <cassert>
#define BUG puts("here!!!");using namespace std;
const int N = 5;
const int M = 30;
char str[N][N];
int p[N][N];
int rp[N][N];
int mmap[M][M];
int pre[M];
bool vis[M];
int n;
int x_id, y_id;
bool dfs(int u) {for(int i = 1; i <= y_id; i++) {if(mmap[u][i] && !vis[i]) {vis[i] = true;if(pre[i] == 0 || dfs(pre[i])) {pre[i] = u;return true;}}}return false;
}
int maxMatch() {memset(pre, 0, sizeof(pre));int num = 0;for(int i = 1; i <= x_id; i++) {memset(vis, 0, sizeof(vis));if(dfs(i)) num++;}return num;
}
int main() {while(cin >> n, n) {for(int i = 0; i < n; i++) {scanf("%s", str[i]);}memset(p, 0, sizeof(p));memset(rp, 0, sizeof(rp));x_id = 0, y_id = 0;for(int i = 0; i < n; i++) {int k = 0;while(k < n) {if(str[i][k] == '.') {++x_id;while(k < n && str[i][k] != 'X') {p[i][k] = x_id;k++;}}else k++;}}for(int i = 0; i < n; i++) {int k = 0;while(k < n) {if(str[k][i] == '.') {++y_id;while(k < n && str[k][i] != 'X') {rp[k][i] = y_id;k++;}}else k++;}}memset(mmap, 0, sizeof(mmap));for(int i = 0; i < n; i++) {for(int j = 0; j < n; j++) {if(str[i][j] == '.') {mmap[p[i][j]][rp[i][j]] = 1;}}}printf("%d\n", maxMatch());}return 0;
}