Language: C++

#include <iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<math.h>
using namespace std;
typedef long long ll;
#define int long long
#define double long double
typedef vector<int> VI;
typedef pair<int, int> pii;
typedef vector<pii> VP;
typedef vector<string> VS;
typedef priority_queue<int> PQ;
template<class T>bool chmax(T &a, const T &b) { if (a < b) { a = b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b < a) { a = b; return 1; } return 0; }
#define fore(i,a) for(auto &i:a)
#define REP(i,n) for(int i=0;i<n;i++)
#define eREP(i,n) for(int i=0;i<=n;i++)
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define eFOR(i,a,b) for(int i=(a);i<=(b);++i)
#define SORT(c) sort((c).begin(),(c).end())
#define rSORT(c) sort((c).rbegin(),(c).rend())
#define LB(x,a) lower_bound((x).begin(),(x).end(),(a))
#define UB(x,a) upper_bound((x).begin(),(x).end(),(a))
#define INF 1000000000
#define LLINF 9223372036854775807
#define mod 1000000007
#define eps 1e-12 
//priority_queue<int,vector<int>, greater<int> > q2;
#define MAX_V 50000
struct edge { int to, cap, rev; };

vector<edge> G[MAX_V];
int level[MAX_V];
int iter[MAX_V];

void add_edge(int from, int to, int cap) {
	G[from].push_back((edge) { to, cap, (int)G[to].size() });
	G[to].push_back((edge) { from, 0LL, (int)G[from].size() - 1 });
}

void bfs(int s) {
	memset(level, -1LL, sizeof(level));
	queue<int> que;
	level[s] = 0;
	que.push(s);
	while (!que.empty()) {
		int v = que.front(); que.pop();
		for (int i = 0; i < G[v].size(); i++) {
			edge &e = G[v][i];
			if (e.cap > 0 && level[e.to] < 0) {
				level[e.to] = level[v] + 1;
				que.push(e.to);
			}
		}
	}
}

int dfs(int v, int t, int f) {
	if (v == t) return f;
	for (int &i = iter[v]; i < G[v].size(); i++) {
		edge &e = G[v][i];
		if (e.cap > 0 && level[v] < level[e.to]) {
			int d = dfs(e.to, t, min(f, e.cap));
			if (d > 0) {
				e.cap -= d;
				G[e.to][e.rev].cap += d;
				return d;
			}
		}
	}
	return 0;
}

int max_flow(int s, int t) {
	int flow = 0;
	for (;;) {
		bfs(s);
		if (level[t] < 0) return flow;
		memset(iter, 0, sizeof(iter));
		int f;
		while ((f = dfs(s, t, INF)) > 0) {
			flow += f;
		}
	}
}


signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);

	int H, W; cin >> H >> W;
	int A = 20001, B = 20002;
	int C = 10000;
	int dx[] = { 0,0,-1,1 };
	int dy[] = { -1,1,0,0 };
	VS S(H);
	REP(i, H)cin >> S[i];

	REP(i, H)if (S[i][0] == 'X' || S[i][W - 1] == 'X') {
		cout << -1 << endl;
		return 0;
	}
	REP(i, W)if (S[0][i] == 'X' || S[H - 1][i] == 'X') {
		cout << -1 << endl;
		return 0;
	}

	REP(i, H) {
		REP(j, W) {
			int k = i * W + j % W;
			int tmp = k;
			if (S[i][j] == 'X') {
				add_edge(k, k + C, INF);
				add_edge(A, k + C, INF);
			}
			else add_edge(k, k + C, 1);

			if (i == 0 || i == H - 1 || j == 0 || j == W - 1) {
				add_edge(k + C, B, INF);
			}

			REP(l, 4) {
				int nx = i + dx[l], ny = j + dy[l];
				if (nx < 0 || nx >= H || ny < 0 || ny >= W)continue;
				k = nx * W + ny % W;
				add_edge(tmp + C, k, INF);
			}
		}
	}

	cout << max_flow(A, B) << endl;

	return 0;
}



Compiler output:
a.cc: In function 'void bfs(long long int)':
a.cc:48:9: error: 'memset' was not declared in this scope
   48 |         memset(level, -1LL, sizeof(level));
      |         ^~~~~~
a.cc:10:1: note: 'memset' is defined in header '<cstring>'; this is probably fixable by adding '#include <cstring>'
    9 | #include<math.h>
  +++ |+#include <cstring>
   10 | using namespace std;
a.cc: In function 'long long int max_flow(long long int, long long int)':
a.cc:85:17: error: 'memset' was not declared in this scope
   85 |                 memset(iter, 0, sizeof(iter));
      |                 ^~~~~~
a.cc:85:17: note: 'memset' is defined in header '<cstring>'; this is probably fixable by adding '#include <cstring>'