結果
問題 | No.459 C-VS for yukicoder |
ユーザー | hashiryo |
提出日時 | 2021-12-16 14:46:04 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 65 ms / 2,000 ms |
コード長 | 6,494 bytes |
コンパイル時間 | 2,800 ms |
コンパイル使用メモリ | 222,256 KB |
実行使用メモリ | 16,608 KB |
最終ジャッジ日時 | 2024-09-13 11:22:52 |
合計ジャッジ時間 | 6,263 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
6,816 KB |
testcase_01 | AC | 2 ms
6,940 KB |
testcase_02 | AC | 2 ms
6,944 KB |
testcase_03 | AC | 2 ms
6,940 KB |
testcase_04 | AC | 2 ms
6,940 KB |
testcase_05 | AC | 2 ms
6,940 KB |
testcase_06 | AC | 2 ms
6,940 KB |
testcase_07 | AC | 2 ms
6,940 KB |
testcase_08 | AC | 2 ms
6,944 KB |
testcase_09 | AC | 2 ms
6,944 KB |
testcase_10 | AC | 2 ms
6,944 KB |
testcase_11 | AC | 2 ms
6,944 KB |
testcase_12 | AC | 2 ms
6,940 KB |
testcase_13 | AC | 2 ms
6,944 KB |
testcase_14 | AC | 2 ms
6,944 KB |
testcase_15 | AC | 3 ms
6,940 KB |
testcase_16 | AC | 3 ms
6,944 KB |
testcase_17 | AC | 2 ms
6,944 KB |
testcase_18 | AC | 2 ms
6,944 KB |
testcase_19 | AC | 2 ms
6,940 KB |
testcase_20 | AC | 2 ms
6,940 KB |
testcase_21 | AC | 61 ms
16,608 KB |
testcase_22 | AC | 26 ms
13,440 KB |
testcase_23 | AC | 65 ms
14,332 KB |
testcase_24 | AC | 21 ms
9,596 KB |
testcase_25 | AC | 10 ms
6,944 KB |
testcase_26 | AC | 5 ms
6,944 KB |
testcase_27 | AC | 5 ms
6,940 KB |
testcase_28 | AC | 9 ms
6,944 KB |
testcase_29 | AC | 11 ms
6,940 KB |
testcase_30 | AC | 5 ms
6,944 KB |
testcase_31 | AC | 10 ms
6,940 KB |
testcase_32 | AC | 3 ms
6,940 KB |
testcase_33 | AC | 13 ms
6,944 KB |
testcase_34 | AC | 13 ms
6,944 KB |
testcase_35 | AC | 3 ms
6,944 KB |
testcase_36 | AC | 9 ms
6,940 KB |
testcase_37 | AC | 3 ms
6,944 KB |
testcase_38 | AC | 13 ms
6,944 KB |
testcase_39 | AC | 3 ms
6,944 KB |
testcase_40 | AC | 8 ms
6,940 KB |
testcase_41 | AC | 3 ms
6,940 KB |
testcase_42 | AC | 7 ms
6,944 KB |
testcase_43 | AC | 11 ms
6,944 KB |
testcase_44 | AC | 4 ms
6,940 KB |
testcase_45 | AC | 4 ms
6,940 KB |
testcase_46 | AC | 4 ms
6,944 KB |
testcase_47 | AC | 3 ms
6,944 KB |
testcase_48 | AC | 11 ms
6,940 KB |
testcase_49 | AC | 2 ms
6,940 KB |
testcase_50 | AC | 11 ms
6,944 KB |
testcase_51 | AC | 3 ms
6,940 KB |
testcase_52 | AC | 6 ms
6,944 KB |
testcase_53 | AC | 3 ms
6,944 KB |
testcase_54 | AC | 13 ms
6,944 KB |
testcase_55 | AC | 5 ms
6,944 KB |
testcase_56 | AC | 8 ms
6,940 KB |
testcase_57 | AC | 3 ms
6,940 KB |
testcase_58 | AC | 13 ms
6,940 KB |
testcase_59 | AC | 4 ms
6,940 KB |
testcase_60 | AC | 6 ms
6,940 KB |
ソースコード
#include <bits/stdc++.h> // #include <atcoder/all> using namespace std; // using namespace atcoder; template <class T, class U> ostream &operator<<(ostream &os, const pair<T, U> &p) { os << "(" << p.first << "," << p.second << ")"; return os; } #ifdef __LOCAL #define debug(x) cerr << __LINE__ << ": " << #x << " = " << (x) << '\n' #define debugArray(x, n) \ cerr << __LINE__ << ": " << #x << " = {"; \ for (long long hoge = 0; (hoge) < (long long)(n); ++(hoge)) \ cerr << ((hoge) ? "," : "") << x[hoge]; \ cerr << "}" << '\n' #define debugMatrix(x, h, w) \ cerr << __LINE__ << ": " << #x << " =\n"; \ for (long long hoge = 0; (hoge) < (long long)(h); ++(hoge)) { \ cerr << ((hoge ? " {" : "{{")); \ for (long long fuga = 0; (fuga) < (long long)(w); ++(fuga)) \ cerr << ((fuga ? ", " : "")) << x[hoge][fuga]; \ cerr << "}" << (hoge + 1 == (long long)(h) ? "}" : ",") << '\n'; \ } #else #define debug(x) (void(0)) #define debugArray(x, n) (void(0)) #define debugMatrix(x, h, w) (void(0)) #endif template <typename FlowAlgo> class MaxFlowLowerBound : public FlowAlgo { using Edge = typename FlowAlgo::Edge; using flow_t = decltype(Edge::cap); std::vector<flow_t> in; int add_edge(int src, int dst, flow_t cap) { int e = this->adj[src].size(); int re = src == dst ? e + 1 : this->adj[dst].size(); this->adj[src].push_back(Edge{dst, re, cap}); this->adj[dst].push_back(Edge{src, e, 0}); return this->m++, re; } public: MaxFlowLowerBound(std::size_t n = 0) : FlowAlgo(n + 2), in(n) {} int add_vertex() { return this->adj.resize(++this->n), in.resize(this->n - 2, 0), this->n - 3; } std::vector<int> add_vertices(const std::size_t size) { std::vector<int> ret(size); std::iota(ret.begin(), ret.end(), this->n - 2); return this->adj.resize(this->n += size), in.resize(this->n - 2, 0), ret; } struct EdgePtr { friend class MaxFlowLowerBound; MaxFlowLowerBound *instance; int v, e; flow_t u; Edge &edge() { return instance->adj[v][e]; } Edge &rev() { Edge &e = edge(); return instance->adj[e.dst][e.rev]; } EdgePtr(MaxFlowLowerBound *instance, int v, int e, flow_t u) : instance(instance), v(v), e(e), u(u) {} public: EdgePtr() = default; int src() { return v; } int dst() { return edge().dst; } flow_t flow() { return u - edge().cap; } flow_t lower() { return flow() - rev().cap; } flow_t upper() { return u; } }; EdgePtr add_edge(int src, int dst, flow_t lower, flow_t upper) { assert(lower <= upper); src += 2, dst += 2; assert(0 <= src && src < this->n); assert(0 <= dst && dst < this->n); this->m++; int e = this->adj[src].size(); int re = src == dst ? e + 1 : this->adj[dst].size(); if (lower * upper <= 0) { this->adj[src].push_back(Edge{dst, re, upper}); this->adj[dst].push_back(Edge{src, e, -lower}); } else if (lower > 0) { in[src - 2] -= lower, in[dst - 2] += lower; this->adj[src].push_back(Edge{dst, re, upper - lower}); this->adj[dst].push_back(Edge{src, e, 0}); } else { in[src - 2] -= upper, in[dst - 2] += upper; this->adj[src].push_back(Edge{dst, re, 0}); this->adj[dst].push_back(Edge{src, e, upper - lower}); } return EdgePtr(this, src, e, upper); } flow_t maxflow(int s, int t) { static constexpr flow_t INF = std::numeric_limits<flow_t>::max(); flow_t sum = 0; for (int i = this->n - 2; i--;) { if (in[i] > 0) add_edge(0, i + 2, in[i]), sum += in[i]; if (in[i] < 0) add_edge(i + 2, 1, -in[i]); } int re = add_edge(t += 2, s += 2, INF); if (this->flow(0, 1, INF) < sum) return -1; // no solution return this->flow(s, t, INF) + this->adj[s][re].cap; } }; template <class flow_t> struct Dinic { Dinic(std::size_t _n = 0) : n(_n), m(0), adj(n) {} protected: struct Edge { int dst, rev; flow_t cap; }; int n, m; std::vector<std::vector<Edge>> adj; std::vector<int> level, iter; inline void levelize(const int &s, const int &t) { level.assign(n, -1), level[s] = 0; std::queue<int> que; for (que.push(s); !que.empty();) { int u = que.front(); que.pop(); for (auto &e : adj[u]) if (e.cap > 0 && level[e.dst] < 0) { level[e.dst] = level[u] + 1; if (e.dst == t) return; que.push(e.dst); } } } inline flow_t dfs(int u, const int &s, flow_t cur) { if (u == s) return cur; flow_t ret = 0; for (int &i = iter[u]; i < adj[u].size(); i++) { Edge &e = adj[u][i], &re = adj[e.dst][e.rev]; if (level[u] <= level[e.dst] || re.cap == 0) continue; flow_t f = dfs(e.dst, s, std::min(cur - ret, re.cap)); if (f <= 0) continue; e.cap += f, re.cap -= f, ret += f; if (ret == cur) return ret; } return level[u] = n, ret; } flow_t flow(int s, int t, flow_t flow_lim) { assert(0 <= s && s < n); assert(0 <= t && t < n); assert(s != t); flow_t ret = 0; for (flow_t f; ret < flow_lim; ret += f) { if (levelize(s, t), level[t] == -1) break; iter.assign(n, 0); if (!(f = dfs(t, s, flow_lim - ret))) break; } return ret; } }; signed main() { cin.tie(0); ios::sync_with_stdio(false); cin.tie(0); ios::sync_with_stdio(false); int H, W, N; cin >> H >> W >> N; int height[W] = {0}; for (int i = 0; i < H; i++) { string S; cin >> S; for (int j = 0; j < W; j++) height[j] += S[j] == '#'; } using MF = MaxFlowLowerBound<Dinic<long long>>; MF graph; MF::EdgePtr e[N][3]; int s = graph.add_vertex(), t = graph.add_vertex(); auto p = graph.add_vertices(N), q = graph.add_vertices(W); for (int i = 0; i < N; i++) { int C; cin >> C; graph.add_edge(s, p[i], 1, 9); for (int j = 0; j < 3; j++) e[i][j] = graph.add_edge(p[i], q[C + j], 0, 3); } for (int i = 0; i < W; i++) graph.add_edge(q[i], t, height[i], height[i]); graph.maxflow(s, t); for (int i = 0; i < N; i++) { string ans[3] = {"...", "...", "..."}; for (int j = 0; j < 3; j++) { auto f = e[i][j].flow(); for (int k = 0; k < f; k++) ans[k][j] = '#'; } for (int j = 0; j < 3; j++) cout << ans[j] << '\n'; } return 0; return 0; }