結果
問題 | No.957 植林 |
ユーザー | QCFium |
提出日時 | 2020-01-23 20:15:10 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 5,606 bytes |
コンパイル時間 | 2,324 ms |
コンパイル使用メモリ | 186,860 KB |
実行使用メモリ | 32,356 KB |
最終ジャッジ日時 | 2024-07-20 04:28:28 |
合計ジャッジ時間 | 34,262 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
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 | 151 ms
26,576 KB |
testcase_04 | AC | 140 ms
25,016 KB |
testcase_05 | AC | 134 ms
27,372 KB |
testcase_06 | AC | 166 ms
28,916 KB |
testcase_07 | AC | 154 ms
25,744 KB |
testcase_08 | WA | - |
testcase_09 | WA | - |
testcase_10 | WA | - |
testcase_11 | WA | - |
testcase_12 | WA | - |
testcase_13 | WA | - |
testcase_14 | WA | - |
testcase_15 | WA | - |
testcase_16 | WA | - |
testcase_17 | WA | - |
testcase_18 | AC | 941 ms
26,884 KB |
testcase_19 | AC | 1,072 ms
27,716 KB |
testcase_20 | AC | 1,020 ms
28,300 KB |
testcase_21 | AC | 1,138 ms
28,856 KB |
testcase_22 | AC | 1,154 ms
29,604 KB |
testcase_23 | AC | 1,258 ms
30,324 KB |
testcase_24 | AC | 1,222 ms
31,156 KB |
testcase_25 | AC | 1,344 ms
31,756 KB |
testcase_26 | AC | 1,370 ms
31,888 KB |
testcase_27 | AC | 1,357 ms
31,796 KB |
testcase_28 | AC | 1,367 ms
31,884 KB |
testcase_29 | AC | 1,379 ms
31,880 KB |
testcase_30 | AC | 1,382 ms
31,792 KB |
testcase_31 | AC | 955 ms
26,756 KB |
testcase_32 | AC | 1,036 ms
27,460 KB |
testcase_33 | AC | 1,025 ms
28,168 KB |
testcase_34 | AC | 1,153 ms
28,832 KB |
testcase_35 | AC | 1,101 ms
29,604 KB |
testcase_36 | AC | 1,246 ms
30,192 KB |
testcase_37 | AC | 1,192 ms
31,284 KB |
testcase_38 | AC | 1,362 ms
31,788 KB |
testcase_39 | AC | 1,338 ms
31,756 KB |
testcase_40 | AC | 1,363 ms
31,884 KB |
testcase_41 | AC | 47 ms
31,372 KB |
testcase_42 | WA | - |
testcase_43 | AC | 85 ms
31,952 KB |
testcase_44 | AC | 107 ms
31,760 KB |
testcase_45 | AC | 2 ms
5,376 KB |
testcase_46 | AC | 3 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]; 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; }