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
| #include <bits/stdc++.h> #define MAX_N 5000 #define MAX_M 20000 #define INF 0x3f3f3f3f using namespace std; template <class T> inline void read(T &x) { x = 0; int c = getchar(), f = 1; for (; !isdigit(c); c = getchar()) if (c == 45) f = -1; for (; isdigit(c); c = getchar()) (x *= 10) += f*(c-'0'); } int n, q, a, b, s, t, cnt, pr[MAX_N+5], cr[MAX_N+5], mxf, mic; char mp[55][55]; int id[2][55][55], sz[2][MAX_N+5], ts[MAX_N+5], ans[MAX_N+5]; struct node {int v, c, w, nxt;} E[MAX_M+5]; void init() {s = 0, t = a+b+1, cnt = 0, memset(pr, -1, sizeof pr);} void insert(int u, int v, int c, int w) {E[cnt] = (node){v, c, w, pr[u]}, pr[u] = cnt++;} void addedge(int u, int v, int c, int w) {insert(u, v, c, w), insert(v, u, 0, -w);} bool SPFA() { queue <int> que; bool inq[MAX_N+5]; int d[MAX_N+5], cr[MAX_N+5]; memset(inq, false, sizeof inq), memset(d, INF, sizeof d); d[s] = 0, que.push(s), inq[s] = true, memset(cr, -1, sizeof cr); while (!que.empty()) { int u = que.front(); que.pop(), inq[u] = false; for (int i = pr[u]; ~i; i = E[i].nxt) { int v = E[i].v, c = E[i].c, w = E[i].w; if (c && d[u]+w < d[v]) { d[v] = d[u]+w, cr[v] = i; if (!inq[v]) que.push(v), inq[v] = true; } } } if (d[t] == INF) return false; int flow = INF; for (int i = cr[t]; ~i; i = cr[E[i^1].v]) flow = min(flow, E[i].c); for (int i = cr[t]; ~i; i = cr[E[i^1].v]) E[i].c -= flow, E[i^1].c += flow; mxf += flow, mic += d[t]; return true; } int main() { read(n); for (int i = 1; i <= n; i++) scanf("%s", mp[i]+1), mp[i][0] = mp[0][i] = '#'; for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) if (mp[i][j] == '.') { if (mp[i][j-1] == '#') id[0][i][j] = ++a, sz[0][a]++; else id[0][i][j] = id[0][i][j-1], sz[0][a]++; } for (int j = 1; j <= n; j++) for (int i = 1; i <= n; i++) if (mp[i][j] == '.') { if (mp[i-1][j] == '#') id[1][i][j] = ++b, sz[1][b]++; else id[1][i][j] = id[1][i-1][j], sz[1][b]++; } init(); for (int i = 1; i <= a; i++) for (int j = 1; j <= sz[0][i]; j++) addedge(s, i, 1, j-1); for (int i = 1; i <= b; i++) for (int j = 1; j <= sz[1][i]; j++) addedge(i+a, t, 1, j-1); for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) if (mp[i][j] == '.') addedge(id[0][i][j], id[1][i][j]+a, 1, 0); read(q); while (SPFA()) ans[mxf] = mic; for (int k; q; q--) read(k), printf("%d\n", ans[k]); return 0; }
|