結果

問題 No.957 植林
ユーザー QCFiumQCFium
提出日時 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
権限があれば一括ダウンロードができます

ソースコード

diff #

#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;
}
0