結果
問題 | No.957 植林 |
ユーザー |
👑 |
提出日時 | 2019-12-19 22:14:14 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 1,280 ms / 2,000 ms |
コード長 | 3,295 bytes |
コンパイル時間 | 907 ms |
コンパイル使用メモリ | 106,296 KB |
実行使用メモリ | 25,368 KB |
最終ジャッジ日時 | 2024-07-07 01:53:52 |
合計ジャッジ時間 | 28,470 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 45 |
ソースコード
#include <cassert>#include <cmath>#include <cstdint>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#include <bitset>#include <complex>#include <deque>#include <functional>#include <iostream>#include <map>#include <numeric>#include <queue>#include <set>#include <sstream>#include <string>#include <unordered_map>#include <unordered_set>#include <utility>#include <vector>using namespace std;using Int = long long;template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; };template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; }template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; }template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; }namespace MF {const int LIM_N = 500010;const int LIM_M = 500010;using wint = Int;const wint wEPS = 0;const wint wINF = 1001001001001001001LL;int n, m, ptr[LIM_N], nxt[LIM_M * 2], zu[LIM_M * 2];wint capa[LIM_M * 2], tof;int lev[LIM_N], see[LIM_N], que[LIM_N], *qb, *qe;void init(int _n) {n = _n; m = 0; fill(ptr, ptr + n, -1);}void ae(int u, int v, wint w0, wint w1 = 0) {nxt[m] = ptr[u]; ptr[u] = m; zu[m] = v; capa[m] = w0; ++m;nxt[m] = ptr[v]; ptr[v] = m; zu[m] = u; capa[m] = w1; ++m;}wint augment(int src, int ink, wint flo) {if (src == ink) return flo;for (int &i = see[src]; ~i; i = nxt[i]) if (capa[i] > wEPS && lev[src] < lev[zu[i]]) {const wint f = augment(zu[i], ink, min(flo, capa[i]));if (f > wEPS) {capa[i] -= f; capa[i ^ 1] += f; return f;}}return 0;}bool solve(int src, int ink, wint flo = wINF) {for (tof = 0; tof + wEPS < flo; ) {qb = qe = que; fill(lev, lev + n, -1);for (lev[*qe++ = src] = 0, see[src] = ptr[src]; qb != qe; ) {const int u = *qb++;for (int i = ptr[u]; ~i; i = nxt[i]) if (capa[i] > wEPS) {const int v = zu[i];if (lev[v] == -1) {lev[*qe++ = v] = lev[u] + 1; see[v] = ptr[v];if (v == ink) goto au;}}}return false;au: for (wint f; (f = augment(src, ink, flo - tof)) > wEPS; tof += f);}return true;}}int main() {int H, W;for (; ~scanf("%d%d", &H, &W); ) {vector<vector<Int>> G(H, vector<Int>(W));for (int x = 0; x < H; ++x) for (int y = 0; y < W; ++y) {scanf("%lld", &G[x][y]);}vector<Int> R(H);for (int x = 0; x < H; ++x) {scanf("%lld", &R[x]);}vector<Int> C(W);for (int y = 0; y < W; ++y) {scanf("%lld", &C[y]);}MF::init(2 + H + W + H * W);for (int x = 0; x < H; ++x) {MF::ae(0, 2 + x, R[x]);}for (int y = 0; y < W; ++y) {MF::ae(0, 2 + H + y, C[y]);}for (int x = 0; x < H; ++x) for (int y = 0; y < W; ++y) {const int v = 2 + H + W + x * W + y;MF::ae(2 + x, v, MF::wINF);MF::ae(2 + H + y, v, MF::wINF);MF::ae(v, 1, G[x][y]);}MF::solve(0, 1);Int ans = 0;for (int x = 0; x < H; ++x) {ans += R[x];}for (int y = 0; y < W; ++y) {ans += C[y];}ans -= MF::tof;printf("%lld\n", ans);}return 0;}