1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
| #include <cstdio>
#include <queue>
#include <algorithm>
using namespace std;
typedef long long LL;
const int INF = 1009999999;
int getint() {
int r = 0, k = 1; char c = getchar();
for (; '0' > c || c > '9'; c = getchar()) if (c == '-') k = -1;
for (; '0' <= c && c <= '9'; c = getchar()) r = r * 10 - '0' + c;
return r * k;
}
namespace Dinic {
struct Edge { int to, next, r; } edge[400010];
int h[200005], cnte = 1, dis[200005], S, T;
queue<int> Q;
void insert(int x, int y, int z) {
edge[++cnte].to = y;
edge[cnte].next = h[x];
edge[cnte].r = z;
h[x] = cnte;
}
void ins(int x, int y, int z) {
insert(x, y, z);
insert(y, x, 0);
}
int dfs(int x, int a) {
if (a == 0 || x == T) return a;
int f, ret = 0;
for (int i = h[x]; i; i = edge[i].next) {
if (dis[edge[i].to] == dis[x] + 1) {
if (f = dfs(edge[i].to, min(edge[i].r, a))) {
ret += f;
a -= f;
edge[i].r -= f;
edge[i^1].r += f;
if (a == 0) break;
}
}
}
if (ret == 0) dis[x] = -1;
return ret;
}
bool bfs() {
for (int i = S; i <= T; ++i) dis[i] = -1;
dis[S] = 0; Q.push(S);
int now;
while (!Q.empty()) {
now = Q.front(); Q.pop();
for (int i = h[now]; i; i = edge[i].next) {
if (edge[i].r && dis[edge[i].to] == -1) {
dis[edge[i].to] = dis[now] + 1;
Q.push(edge[i].to);
}
}
}
return dis[T] != -1;
}
int go() {
int flow = 0;
while (bfs())
flow += dfs(S, INF);
return flow;
}
}
using Dinic::S;
using Dinic::T;
int lid[55][55], hid[55][55], tot, n, m, ans, tmp;
char str[55][55];
int main() {
//freopen("I:\\input.txt", "r", stdin);
n = getint(); m = getint();
for (int i = 1; i <= n; ++i)
scanf("%s", str[i]+1);
for (int i = 1; i <= n; ++i) {
++tot;
for (int j = 1; j <= m; ++j) {
if (str[i][j] == '#') ++tot;
else hid[i][j] = tot;
}
}
tmp = tot;
for (int j = 1; j <= m; ++j) {
++tot;
for (int i = 1; i <= n; ++i) {
if (str[i][j] == '#') ++tot;
else lid[i][j] = tot;
}
}
S = 0; T = ++tot;
for (int i = 1; i <= tmp; ++i) Dinic::ins(S, i, 1);
for (int i = tmp + 1; i < tot; ++i) Dinic::ins(i, T, 1);
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
if (str[i][j] == '*')
Dinic::ins(hid[i][j], lid[i][j], 1);
ans = Dinic::go();
printf("%d", ans);
}
|