結果
問題 | No.957 植林 |
ユーザー | QCFium |
提出日時 | 2020-01-23 20:18:25 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 1,386 ms / 2,000 ms |
コード長 | 5,636 bytes |
コンパイル時間 | 2,260 ms |
コンパイル使用メモリ | 185,520 KB |
実行使用メモリ | 31,884 KB |
最終ジャッジ日時 | 2024-07-20 04:32:57 |
合計ジャッジ時間 | 33,945 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,376 KB |
testcase_02 | AC | 2 ms
5,376 KB |
testcase_03 | AC | 154 ms
26,580 KB |
testcase_04 | AC | 149 ms
24,888 KB |
testcase_05 | AC | 143 ms
27,368 KB |
testcase_06 | AC | 169 ms
28,864 KB |
testcase_07 | AC | 153 ms
25,744 KB |
testcase_08 | AC | 67 ms
27,316 KB |
testcase_09 | AC | 65 ms
27,316 KB |
testcase_10 | AC | 71 ms
28,380 KB |
testcase_11 | AC | 68 ms
27,580 KB |
testcase_12 | AC | 71 ms
26,908 KB |
testcase_13 | AC | 54 ms
23,948 KB |
testcase_14 | AC | 69 ms
29,852 KB |
testcase_15 | AC | 61 ms
26,748 KB |
testcase_16 | AC | 55 ms
23,920 KB |
testcase_17 | AC | 54 ms
25,472 KB |
testcase_18 | AC | 961 ms
26,884 KB |
testcase_19 | AC | 1,023 ms
27,588 KB |
testcase_20 | AC | 1,031 ms
28,296 KB |
testcase_21 | AC | 1,186 ms
28,860 KB |
testcase_22 | AC | 1,134 ms
29,604 KB |
testcase_23 | AC | 1,304 ms
30,320 KB |
testcase_24 | AC | 1,289 ms
31,284 KB |
testcase_25 | AC | 1,382 ms
31,884 KB |
testcase_26 | AC | 1,380 ms
31,756 KB |
testcase_27 | AC | 1,370 ms
31,884 KB |
testcase_28 | AC | 1,348 ms
31,756 KB |
testcase_29 | AC | 1,372 ms
31,880 KB |
testcase_30 | AC | 1,386 ms
31,756 KB |
testcase_31 | AC | 946 ms
26,880 KB |
testcase_32 | AC | 1,101 ms
27,592 KB |
testcase_33 | AC | 1,057 ms
28,424 KB |
testcase_34 | AC | 1,225 ms
28,860 KB |
testcase_35 | AC | 1,126 ms
29,476 KB |
testcase_36 | AC | 1,193 ms
30,196 KB |
testcase_37 | AC | 1,201 ms
31,156 KB |
testcase_38 | AC | 1,310 ms
31,884 KB |
testcase_39 | AC | 1,286 ms
31,880 KB |
testcase_40 | AC | 1,349 ms
31,884 KB |
testcase_41 | AC | 48 ms
31,496 KB |
testcase_42 | AC | 48 ms
31,372 KB |
testcase_43 | AC | 86 ms
31,656 KB |
testcase_44 | AC | 108 ms
31,880 KB |
testcase_45 | AC | 2 ms
5,376 KB |
testcase_46 | AC | 2 ms
5,376 KB |
testcase_47 | AC | 2 ms
5,376 KB |
ソースコード
#include <bits/stdc++.h> int ri() { int n; scanf("%d", &n); return n; } /* copied from https://gist.github.com/MiSawa/9759784 */ /* edited by QCFium */ struct Dinic { private: typedef int64_t Cap; static const Cap INF = 1000000000000000000; struct LCNode { typedef LCNode *Ptr; Ptr ch[2], par, min_node; Cap val, min_val, lazy; int name; LCNode() : par(0), min_node(this), val(INF), min_val(INF), lazy(0) { ch[0] = ch[1] = 0; } inline void push() { if (lazy == 0) return; val += lazy; min_val += lazy; for (int i = 0; i < 2; i++) if (ch[i]) ch[i]->lazy += lazy; lazy = 0; } inline void update() { push(); if (ch[0]) { min_val = ch[0]->min_val + ch[0]->lazy; min_node = ch[0]->min_node; } if (!ch[0] || min_val > val) { min_val = val; min_node = this; } if (ch[1] && min_val > ch[1]->min_val + ch[1]->lazy) { min_val = ch[1]->min_val + ch[1]->lazy; min_node = ch[1]->min_node; } } inline void set_value(Cap v) { expose(); val = v; update(); } inline Cap get_value() { expose(); return val; } inline Ptr get_min_node_on_path() { expose(); return min_node; } inline void add_to_path(Cap c) { expose(); lazy += c; push(); } inline int state() { if(par && par->ch[0] == this) return -1; if(par && par->ch[1] == this) return +1; return 0; } inline void rotate() { Ptr p = par; p->push(); push(); bool lr = state()+1; if (p->state()) p->par->ch[p->state()>0] = this; par = p->par; p->ch[lr] = ch[!lr]; if (ch[!lr]) ch[!lr]->par = p; (p->par = this)->ch[!lr] = p; p->update(); update(); } inline void splay() { while (state()) { int s = state() * par->state(); if (s) (s == 1 ? par : this)->rotate(); rotate(); } push(); } inline void expose() { if (!par) return; for (Ptr p = this; p; p = p->par) p->splay(); for (Ptr p = this; p->par; p = p->par) p->par->ch[1] = p; splay(); } inline void cut() { expose(); if (!ch[0]) return; ch[0]->par = 0; ch[0]->push(); ch[0] = 0; update(); } inline void link_to(Ptr p) { expose(); par = p; } inline Ptr find_root() { expose(); Ptr p = this; while (p->ch[0]) p = p->ch[0]; p->expose(); return p; } }; struct E{ int dst; Cap cap; int rev; E(int dst, Cap cap, int rev) : dst(dst), cap(cap), rev(rev) {} }; int n; std::vector<std::vector<E> > g; std::vector<int> level, active; std::vector<LCNode> lc; inline void unuse_edge(E &e) { E &ee = g[e.dst][e.rev]; int u = ee.dst; Cap use = ee.cap - lc[u].get_value(); e.cap += use; ee.cap -= use; active[u] = false; lc[u].cut(); lc[u].set_value(INF); } inline void init(){ lc.resize(n); active.assign(n, false); for (int i = 0; i < n; i++) lc[i].name = i; } Cap dfs(const int &s, const int &t) { std::vector<int> iter(n); for (int i = 0; i < n; i++) iter[i] = (int) (g[i].size()) - 1; Cap res = 0; while(1){ const int &u = lc[t].find_root()->name; if (u == s) { Cap f = lc[t].get_min_node_on_path()->get_value(); res += f; lc[t].add_to_path(-f); while (1) { int v = lc[t].get_min_node_on_path()->name; Cap f = lc[v].get_value(); if (f > 0) break; unuse_edge(g[v][iter[v]]); } } else { for (int &i = iter[u]; i >= 0; --i) { E &e = g[u][i], &ee = g[e.dst][e.rev]; int v = e.dst; if (level[u]-1 != level[v] || ee.cap <= 0) continue; active[u] = true; lc[u].set_value(ee.cap); lc[u].link_to(&lc[v]); break; } if (active[u]) continue; if (u == t) break; level[u] = -1; for (auto& e : g[u]) if (active[e.dst] && iter[e.dst] == e.rev) unuse_edge(g[e.dst][e.rev]); } } for (int i = 0; i < n; i++) if (active[i]) unuse_edge(g[i][iter[i]]); return res; } public: Dinic(int n) : n(n), g(n) {} inline void add_hen(int src, int dst, Cap cap, bool direct) { if (src == dst) return; g[src].push_back(E(dst,cap,g[dst].size())); g[dst].push_back(E(src,direct?0:cap ,g[src].size() - 1)); } Cap run(int s, int t) { // O(NMlogN) init(); std::vector<int> q(n); for (Cap flow = 0; ;) { level.assign(n, -1); int ql = 0, qr = 0; level[q[qr++] = s] = 0; while (ql != qr && level[t] == -1) { int u = q[ql++]; for (auto& e : g[u]) if (e.cap > 0 && level[e.dst] == -1) level[ q[qr++] = e.dst ] = level[u] + 1; } if (level[t] == -1) return flow; flow += dfs(s, t); } } }; int main() { int h = ri(); int w = ri(); int a[h][w]; for (auto &i : a) for (auto &j : i) j = ri(); int b[h]; for (auto &i : b) i = ri(); int c[w]; for (auto &i : c) i = ri(); Dinic dinic(h + w + h * w + 2); int goal = h + w + h * w + 1; int64_t base = 0; for (int i = 0; i < h; i++) { int64_t cost = std::accumulate(a[i], a[i] + w, 0LL) - b[i]; if (cost < 0) base += cost; dinic.add_hen(0, i + 1, std::max<int64_t>(0, cost), true); dinic.add_hen(i + 1, goal, std::max<int64_t>(0, -cost), true); } for (int i = 0; i < w; i++) { int64_t cost = -c[i]; for (int j = 0; j < h; j++) cost += a[j][i]; if (cost < 0) base += cost; dinic.add_hen(0, h + 1 + i, std::max<int64_t>(0, cost), true); dinic.add_hen(h + 1 + i, goal, std::max<int64_t>(0, -cost), true); } for (int i = 0; i < h; i++) for (int j = 0; j < w; j++) { base += -a[i][j]; dinic.add_hen(i + 1, h + w + i * w + j + 1, 10000000000000000, true); dinic.add_hen(h + j + 1, h + w + i * w + j + 1, 10000000000000000, true); dinic.add_hen(h + w + i * w + j + 1, goal, a[i][j], true); } std::cout << std::max<int64_t>(0, -(base + dinic.run(0, goal))) << std::endl; return 0; }