Cod sursa(job #2066365)

Utilizator oldatlantianSerban Cercelescu oldatlantian Data 14 noiembrie 2017 22:19:07
Problema Pixels Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.19 kb
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
using namespace std;

ifstream fi("pixels.in");
ofstream fo("pixels.out");

const int L = 100, N = L * L + 5, M = N * 12;

const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, 1, 0, -1};

struct Edge {
	int u, v, cap, flow; } edges[M];

vector<int> g[N];
int far[N], a[L][L], b[L][L];

int n, ant, src, snk;

static void make_edg(const int &u, const int &v, const int &cap) {
	static int bp = 2;
	g[u].push_back(bp); edges[bp++] = {u, v, cap, 0};
	g[v].push_back(bp); edges[bp++] = {v, u, cap, 0}; }

static inline bool pump() {
	static deque<int> dq;
	int u, cap;

	memset(far, 0x00, sizeof far);
	dq.push_back(src);
	far[src] = -1;

	while (!dq.empty()) {
		u = dq.front();
		dq.pop_front();

		for (auto v: g[u]) if (edges[v].cap - edges[v].flow > 0 && !far[edges[v].v]) {
			dq.push_back(edges[v].v);
			far[edges[v].v] = v; } }

	if (far[snk])
	for (auto v: g[snk]) if (far[edges[v^= 1].u]) {
		u = edges[v].u;
		cap = edges[v].cap - edges[v].flow;
		
		while (u != src && cap > 0) {
			cap = min(cap, edges[far[u]].cap - edges[far[u]].flow);
			u = edges[far[u]].u; }

		ant-= cap;
		if (!cap)
			continue;

		u = edges[v].u;
		edges[v].flow+= cap;
		edges[v ^ 1].flow-= cap;

		while (u != src) {
			edges[far[u]].flow+= cap;
			edges[far[u] ^ 1].flow-= cap;
			u = edges[far[u]].u; } }

	return far[snk]; }

static inline bool ok(const int &x, const int &y) {
	return (0 <= x && x < n) && (0 <= y && y < n); }

static inline int cod(const int &x, const int &y) {
	return x * n + y + 1; }

int main() {
	int nx, ny, t;

	fi >> n;
	for (int i = 0; i < n; ++i)
	for (int j = 0; j < n; ++j)
		fi >> a[i][j],
		ant+= a[i][j];

	for (int i = 0; i < n; ++i) 
	for (int j = 0; j < n; ++j)
		fi >> b[i][j],
		ant+= b[i][j];

	src = n * n + 2;
	snk = n * n + 3;

	for (int i = 0; i < n; ++i)
	for (int j = 0; j < n; ++j) {
		make_edg(src, cod(i, j), a[i][j]);
		make_edg(snk, cod(i, j), b[i][j]);
		for (int d = 0; d < 4; ++d) {
			fi >> t;

			nx = i + dx[d];
			ny = j + dy[d];

			if (ok(nx, ny) && (i + j) % 2)
				make_edg(cod(i, j), cod(nx, ny), t); } }

	while (pump());

	fo << ant << endl;

	return 0; }