結果
| 問題 | No.957 植林 |
| コンテスト | |
| ユーザー |
ei1333333
|
| 提出日時 | 2019-12-18 01:03:37 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.89.0) |
| 結果 |
AC
|
| 実行時間 | 1,010 ms / 2,000 ms |
| コード長 | 8,224 bytes |
| 記録 | |
| コンパイル時間 | 3,555 ms |
| コンパイル使用メモリ | 215,720 KB |
| 最終ジャッジ日時 | 2025-01-08 12:12:52 |
|
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 45 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
using int64 = long long;
const int mod = 1e9 + 7;
// const int mod = 998244353;
const int64 infll = (1LL << 62) - 1;
const int inf = (1 << 30) - 1;
struct IoSetup {
IoSetup() {
cin.tie(nullptr);
ios::sync_with_stdio(false);
cout << fixed << setprecision(15);
cerr << fixed << setprecision(15);
}
} iosetup;
template< typename T1, typename T2 >
ostream &operator<<(ostream &os, const pair< T1, T2 > &p) {
os << p.first << " " << p.second;
return os;
}
template< typename T1, typename T2 >
istream &operator>>(istream &is, pair< T1, T2 > &p) {
is >> p.first >> p.second;
return is;
}
template< typename T >
ostream &operator<<(ostream &os, const vector< T > &v) {
for(int i = 0; i < (int) v.size(); i++) {
os << v[i] << (i + 1 != v.size() ? " " : "");
}
return os;
}
template< typename T >
istream &operator>>(istream &is, vector< T > &v) {
for(T &in : v) is >> in;
return is;
}
template< typename T1, typename T2 >
inline bool chmax(T1 &a, T2 b) { return a < b && (a = b, true); }
template< typename T1, typename T2 >
inline bool chmin(T1 &a, T2 b) { return a > b && (a = b, true); }
template< typename T = int64 >
vector< T > make_v(size_t a) {
return vector< T >(a);
}
template< typename T, typename... Ts >
auto make_v(size_t a, Ts... ts) {
return vector< decltype(make_v< T >(ts...)) >(a, make_v< T >(ts...));
}
template< typename T, typename V >
typename enable_if< is_class< T >::value == 0 >::type fill_v(T &t, const V &v) {
t = v;
}
template< typename T, typename V >
typename enable_if< is_class< T >::value != 0 >::type fill_v(T &t, const V &v) {
for(auto &e : t) fill_v(e, v);
}
template< typename F >
struct FixPoint : F {
FixPoint(F &&f) : F(forward< F >(f)) {}
template< typename... Args >
decltype(auto) operator()(Args &&... args) const {
return F::operator()(*this, forward< Args >(args)...);
}
};
template< typename F >
inline decltype(auto) MFP(F &&f) {
return FixPoint< F >{forward< F >(f)};
}
#define rep(i, n) for(int i = 0; i < (n); ++i)
#define REP(i, b, n) for(int i = (b); i < (n); ++i)
#define let(v, x) __typeof(x) v = (x)
#define foreach(i, v) for(let(i, (v).begin());i!=(v).end();i++)
struct DinicLC {//{{{
typedef int64 Cap;
static const Cap INF = 1LL << 60;
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;
rep(i, 2) 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;
vector< vector< E > > g;
DinicLC(int n) : n(n), g(n) {}
inline void add_edge(int src, int dst, Cap cap) {//{{{
if(src == dst) return;
g[src].push_back(E(dst, cap, g[dst].size()));
g[dst].push_back(E(src, 0, g[src].size() - 1));
}//}}}
inline void add_undirected_edge(int src, int dst, Cap cap) {//{{{
if(src == dst) return;
g[src].push_back(E(dst, cap, g[dst].size()));
g[dst].push_back(E(src, cap, g[src].size() - 1));
}//}}}
vector< int > level, active;
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);
rep(u, n) lc[u].name = u;
}//}}}
Cap dfs(const int &s, const int &t) {//{{{
vector< int > iter(n);
rep(u, n) iter[u] = (int) (g[u].size()) - 1;
Cap res = 0;
while(true) {
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(true) {
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;
foreach(e, g[u]) if(active[e->dst] && iter[e->dst] == e->rev)
unuse_edge(g[e->dst][e->rev]);
}
}
rep(u, n) if(active[u]) unuse_edge(g[u][iter[u]]);
return res;
}//}}}
Cap run(int s, int t) {//{{{
init();
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++];
foreach(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, W;
cin >> H >> W;
vector< vector< int64 > > G(H, vector< int64 >(W));
for(int i = 0; i < H; i++) {
for(int j = 0; j < W; j++) cin >> G[i][j];
}
vector< int64 > R(H), C(W);
for(int i = 0; i < H; i++) cin >> R[i];
for(int i = 0; i < W; i++) cin >> C[i];
int64 sum = accumulate(begin(R), end(R), 0LL) + accumulate(begin(C), end(C), 0LL);
DinicLC flow(H * W + H + W + 2);
int S = H * W + H + W;
int T = S + 1;
for(int i = 0; i < H; i++) {
for(int j = 0; j < W; j++) {
flow.add_edge(S, i * W + j, G[i][j]);
flow.add_edge(i * W + j, H * W + i, flow.INF);
flow.add_edge(i * W + j, H * W + H + j, flow.INF);
}
}
for(int i = 0; i < H; i++) {
flow.add_edge(H * W + i, T, R[i]);
}
for(int i = 0; i < W; i++) {
flow.add_edge(H * W + H + i, T, C[i]);
}
cout << sum - flow.run(S, T) << endl;
}
ei1333333