diff --git a/Luogu/P3191/P3191.cpp b/Luogu/P3191/P3191.cpp new file mode 100644 index 00000000..92130191 --- /dev/null +++ b/Luogu/P3191/P3191.cpp @@ -0,0 +1,211 @@ +#include +#include +#include +#include +#include + +using std::cin; +using std::cout; +const char endl = '\n'; + +const int N = 25, + M = N * N, + E = 3e5 + 5; +const int INF = 0x3f3f3f3f; + +const int d[][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; + +int n, m, s, t, cnt, f[M][M]; +char g[N][N]; +int idx, head[E], ver[E << 1], edge[E << 1], next[E << 1]; +int cur[E << 1], dist[E << 1]; +bool vis[E << 1], vis2[M][M]; + +int id(int x, int y) { + return (x - 1) * m + y; +} + +void add(int u, int v, int w) { + next[idx] = head[u]; + ver[idx] = v; + edge[idx] = w; + head[u] = idx++; +} + +bool bfs() { + std::fill(std::begin(dist), std::end(dist), 0); + + std::queue q; + + q.emplace(s); + dist[s] = 1; + cur[s] = head[s]; + + while (!q.empty()) { + int u = q.front(); + q.pop(); + + for (int i = head[u]; ~i; i = next[i]) { + int v = ver[i], + w = edge[i]; + + if (!dist[v] && w) { + dist[v] = dist[u] + 1; + cur[v] = head[v]; + + if (v == t) return true; + + q.emplace(v); + } + } + } + + return false; +} + +int dinic(int u, int limit) { + if (u == t) return limit; + + int flow = 0; + + for (int i = cur[u]; ~i && flow < limit; i = next[i]) { + cur[u] = i; + + int v = ver[i], + w = edge[i]; + + if (dist[v] == dist[u] + 1 && w) { + int k = dinic(v, std::min(w, limit - flow)); + + if (!k) dist[v] = 0; + + edge[i] -= k; + edge[i ^ 1] += k; + flow += k; + } + } + + return flow; +} + +bool check(int x) { + idx = 0; + std::fill(std::begin(head), std::end(head), -1); + + for (int i = 1; i <= n; i++) { + for (int j = 1; j <= m; j++) { + if (g[i][j] == '.') { + add(s, id(i, j), 1); + add(id(i, j), s, 0); + } else if (g[i][j] == 'D') { + for (int k = 0; k < x; k++) { + add(n * m + id(i, j) * x + k, t, 1); + add(t, n * m + id(i, j) * x + k, 0); + } + + for (int k = 0; k < x - 1; k++) { + add(n * m + id(i, j) * x + k, n * m + id(i, j) * x + k + 1, INF); + add(n * m + id(i, j) * x + k + 1, n * m + id(i, j) * x + k, 0); + } + + for (int p = 1; p <= n; p++) { + for (int q = 1; q <= m; q++) { + if (g[p][q] == '.') { + int d = f[id(p, q)][id(i, j)]; + + if (d <= x) { + add(id(p, q), n * m + id(i, j) * x + d - 1, INF); + add(n * m + id(i, j) * x + d - 1, id(p, q), 0); + } + } + } + } + } + } + } + + int res = 0; + + while (bfs()) { + while (int flow = dinic(s, INF)) res += flow; + } + + return res == cnt; +} + +int main() { + std::ios::sync_with_stdio(false); + cin.tie(nullptr); + + memset(f, 0x3f, sizeof(f)); + + cin >> n >> m; + + s = 0, t = 10000; + + for (int i = 1; i <= n; i++) { + for (int j = 1; j <= m; j++) { + cin >> g[i][j]; + + if (g[i][j] == '.') cnt++; + } + } + + for (int i = 1; i <= n; i++) { + for (int j = 1; j <= m; j++) { + if (g[i][j] == 'D') { + memset(vis2, 0x00, sizeof(vis2)); + + f[id(i, j)][id(i, j)] = 0; + + std::queue> q; + + q.emplace(i, j); + + while (!q.empty()) { + int x = q.front().first, + y = q.front().second; + q.pop(); + + for (auto d : d) { + int xx = x + d[0], + yy = y + d[1]; + + if (xx < 0 || xx > n || yy < 0 || yy > m || g[xx][yy] != '.' || vis2[xx][yy]) continue; + + vis2[xx][yy] = true; + + if (f[id(xx, yy)][id(i, j)] > f[id(x, y)][id(i, j)] + 1) { + f[id(xx, yy)][id(i, j)] = f[id(x, y)][id(i, j)] + 1; + + q.emplace(xx, yy); + } + } + } + } + } + } + + int l = 0, + r = cnt, + res = -1; + + while (l <= r) { + int mid = (l + r) >> 1; + + if (check(mid)) { + r = mid - 1; + res = mid; + } else { + l = mid + 1; + } + } + + if (res == -1) { + cout << "impossible" << endl; + } else { + cout << res << endl; + } + + return 0; +}