Problem:
D: Surround the Castle
You just started a simulation game of the Age of Civil Wars! In this game, there is an infinite two-dimensional grid. Each cell in this grid is either a
plain cell
, a
castle cell
or a
moat cell
.
Your
territory
is a rectangle of cells that consists of $R$ rows and $C$ columns. Your territory now consists of only one castle cell and the
other $RC - 1$ plain cells. You can change each plain cell to a moat cell by paying some costs depending on the cell.
To protect your castle cell from foreign enemies, you decided to
surround
your castle cell with moat cells. More precisely, your castle cell is considered surrounded by moat cells if any cell outside your territory can't be reached from your castle cell by repeatedly moving to a cell that is not your moat cell and is horizontally, vertically, or diagonally adjacent to the current cell.
Figures D-1 to D-3 show examples of your territories whose borders are depicted as bold rectangles. In Figure D-1 the moat cells, which
are depicted as blue squares, surround the castle cell. On the other hand, in Figures D-2 and D-3 the moat cells don't surround the castle cells.
Figure D-1. An example of a castle cell surrounded by moat cells
Figure D-2. An example of a castle cell not surrounded by moat cells
Figure D-3. Another example of a castle cell not surrounded by moat cells
You are given the location of your castle cell and the cost to change each of the other plain cells to a moat cell. Find the minimum total
cost to surround your castle cell with moat cells.
Input
The input consists of a single test case of the following format.
$R$ $C$
$a_{11}$ ... $a_{1C}$
:
$a_{R1}$ ... $a_{RC}$
$R$ and $C$ represent the number of rows and columns of your territory ($3 \leq R \leq 20, 3 \leq C \leq 10^4$). Each $a_{ij}$ ($a_{ij} = −1$ or $1 \leq a_{ij} \leq 10^9$) gives the information of the cell of the $i$-th row and the $j$-th column of your territory. If it is $-1$, then the cell is your castle cell.
Otherwise, the cell is initially a plain cell and $a_{ij}$ equals the cost to change it to a moat cell.
It is guaranteed that there is exactly one castle cell in the input. In addition, your castle cell never locates at the first row, the $R$-th row,
the first column nor the $C$-th column. In other words, it is guaranteed that you can surround your castle cell with moat cells.
Output
Output the minimum total cost to surround your castle cell with moat cells.
Examples
Input 1
5 5
1 1 1 1 1
1 9 9 9 1
1 9 -1 9 1
1 9 9 9 1
1 1 1 1 1
Output 1
16
Input 2
6 8
13 15 25 28 88 90 74 87
20 85 20 18 14 26 18 56
40 54 11 90 91 13 41 66
30 82 51 -1 38 22 86 62
27 55 13 51 42 64 77 36
12 90 43 25 11 60 60 72
Output 2
319

Submitted solutions:

code_snippet: #ifdef NACHIA
#define _GLIBCXX_DEBUG
#else
#define NDEBUG
#endif
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <queue>
using i64 = long long;
using u64 = unsigned long long;
#define rep(i,n) for(i64 i=0; i<i64(n); i++)
const i64 INF = 1001001001001001001;
template<typename A> void chmin(A& l, const A& r){ if(r < l) l = r; }
template<typename A> void chmax(A& l, const A& r){ if(l < r) l = r; }
using namespace std;
template<class E> using nega_queue = priority_queue<E, vector<E>, greater<E>>;

void testcase(){
    i64 H, W; cin >> H >> W;
    vector<vector<i64>> A(H, vector<i64>(W));
    rep(y,H) rep(x,W) cin >> A[y][x];
    i64 sy = 0, sx = 0;
    rep(y,H) rep(x,W) if(A[y][x] == -1){ sy = y; sx = x; }
    if(sy * 2 >= H){ sy = H-1-sy; reverse(A.begin(), A.end()); }
    auto Idx = [&](i64 y, i64 x){ return y * W + x; };
    vector<vector<pair<i64,i64>>> adj(H*W);
    rep(y,H) rep(x,W-1){
        if(y == sy && x == sx) continue;
        if(y == sy && x + 1 == sx) continue;
        i64 c = 0;
        if(y < sy && x == sx) c = 1;
        adj[Idx(y,x)].push_back({Idx(y,x+1),c});
        adj[Idx(y,x+1)].push_back({Idx(y,x),c});
    }
    rep(y,H-1) rep(x,W){
        if(y == sy && x == sx) continue;
        if(y + 1 == sy && x == sx) continue;
        adj[Idx(y,x)].push_back({Idx(y+1,x),0});
        adj[Idx(y+1,x)].push_back({Idx(y,x),0});
    }
    vector<i64> cost(H*W);
    rep(y,H) rep(x,W) cost[Idx(y,x)] = A[y][x];
    i64 ans = INF;
    rep(ssy,sy){
        vector<i64> dist[2];
        rep(f,2) dist[f].assign(H*W, INF);
        nega_queue<pair<i64,pair<i64,i64>>> que;
        auto check = [&](i64 c, i64 p, i64 d) -> void {
            if(dist[c][p] <= d) return;
            dist[c][p] = d;
            que.push({ dist[c][p], { c,p } });
        };
        check(0, Idx(ssy,sx), 0);
        while(que.size()){
            auto [d,cp] = que.top(); que.pop();
            auto [c,p] = cp;
            if(dist[c][p] != d) continue;
            for(auto [q,dc] : adj[p]){
                check(c^dc, q, d+cost[q]);
            }
        }
        chmin(ans, dist[1][Idx(ssy,sx)]);
    }
    cout << ans << "\n";
}

int main(){
    ios::sync_with_stdio(false); cin.tie(nullptr);
    testcase();
    return 0;
}
accuracy: 1
time_ms: 540
memory_kb: 41200
final_rank: 4

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, l, r) for (int i = (l); i < r; ++i)
#define rrep(i, l, r) for (int i = (r - 1); i >= l; --i)
#define all(c) begin(c), end(c)

#ifdef LOCAL
#define debug(...) debug_impl(#__VA_ARGS__, __VA_ARGS__)
template <class H, class... Ts> void debug_impl(string s, H&& h, Ts &&... ts) {
  cerr << '(' << s << "): (" << forward<H>(h);
  ((cerr << ", " << forward<Ts>(ts)), ..., (cerr << ")\n"));
}
#else
#define debug(...) void(0)
#endif

template <class T> bool chmax(T& a, const T& b) {
  return b > a ? (a = b, true) : false;
}
template <class T> bool chmin(T& a, const T& b) {
  return b < a ? (a = b, true) : false;
}

template <class T> istream& operator>>(istream& in, vector<T>& v) {
  for (auto& e : v) in >> e;
  return in;
}
template <class ... Args> void read(Args &... args) {
  (cin >> ... >> args);
}
template <class T> ostream& operator<<(ostream& out, const vector<T>& v) {
  int n = v.size();
  rep(i, 0, n) {
    out << v[i];
    if (i + 1 != n) out << ' ';
  }
  return out;
}
template <class H, class ... Ts> void print(H&& h, Ts &&...ts) {
  cout << h, ((cout << " " << forward<Ts>(ts)), ..., (cout << "\n"));
}

struct io_setup_ {
  io_setup_() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    cout << fixed << setprecision(10);
    cerr << fixed << setprecision(10);
  }
} io_setup{};

constexpr int dx[4]{ 1, 0, -1, 0 };
constexpr int dy[4]{ 0, 1, 0, -1 };

bool in(int x, int l, int r) {
  return l <= x and x < r;
}

constexpr long long inf = numeric_limits<long long>::max() / 2;

int main() {
  int r, c;
  read(r, c);

  vector a(r, vector<long long>(c));
  read(a);

  int px = -1, py = -1;
  rep(i, 0, r) rep(j, 0, c) {
    if (a[i][j] == -1) {
      px = i, py = j;
    }
  }

  long long ans = inf;

  rep(sx, 0, px) {
    using node = tuple<bool, int, int>;

    using state = pair<long long, node>;
    priority_queue<state, vector<state>, greater<state>> pq;
    vector dist(2, vector(r, vector<long long>(c, inf)));
    pq.emplace(dist[0][sx][py] = a[sx][py], node(0, sx, py));

    while (pq.size()) {
      auto [du, u] = pq.top();
      auto [f, cx, cy] = u;
      pq.pop();
      if (dist[f][cx][cy] != du) continue;

      rep(dr, 0, 4) {
        const int nx = cx + dx[dr], ny = cy + dy[dr];
        if (not (in(nx, 0, r) and in(ny, 0, c))) continue;
        if (nx == px and ny == py) continue;

        int nf = f;
        if (ny == py and cy == ny + 1 and nx < px) {
          nf ^= 1;
        } else if (cy == py and ny == cy + 1 and nx < px) {
          nf ^= 1;
        }

        if (chmin(dist[nf][nx][ny], du + a[nx][ny])) {
          pq.emplace(dist[nf][nx][ny], node(nf, nx, ny));
        }
      }
    }

    rep(tx, px + 1, r) {
      rep(f, 0, 2) {
        long long cost = dist[f][tx][py] + dist[f ^ 1][tx][py] - a[sx][py] - a[tx][py];
        debug(sx, py, tx, py, cost);
        chmin(ans, cost);
      }
    }
  }
  print(ans);
}
accuracy: 1
time_ms: 690
memory_kb: 18840
final_rank: 1

code_snippet: #include <iostream>
#include <vector>
#include <queue>
#include <tuple>

template <class T>
using MinHeap = std::priority_queue<T, std::vector<T>, std::greater<T>>;

using namespace std;
using lint = long long;

constexpr lint INF = 1LL << 60;
const vector<pair<int, int>> dxys{{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

void solve() {
    int h, w;
    cin >> h >> w;

    auto xss = vector(h, vector(w, 0LL));
    for (auto& xs : xss) {
        for (auto& x : xs) cin >> x;
    }

    int sx = -1, sy = -1;
    for (int x = 0; x < h; ++x) {
        for (int y = 0; y < w; ++y) {
            if (xss[x][y] == -1) sx = x, sy = y;
        }
    }

    lint ans = INF;
    for (int px = 0; px < sx; ++px) {
        // (px, sy)からスタート

        auto dist = vector(h, vector(w, vector(2, INF)));
        dist[px][sy][0] = 0;
        // 現在の座標、(sx, sy)の右を横切った回数mod2

        MinHeap<tuple<lint, int, int, int>> heap;
        heap.emplace(0, px, sy, 0);

        while (!heap.empty()) {
            auto [d, x, y, p] = heap.top();
            heap.pop();
            if (d > dist[x][y][p]) continue;

            for (auto [dx, dy] : dxys) {
                auto nx = x + dx, ny = y + dy;

                if (nx < 0 || h <= nx ||
                    ny < 0 || w <= ny ||
                    xss[nx][ny] == -1) continue;

                auto nd = d + xss[nx][ny];

                // 横切り判定
                auto np = p;
                if (sy < ny && (x <= sx) != (nx <= sx)) np = 1 - np;

                if (nd < dist[nx][ny][np]) {
                    dist[nx][ny][np] = nd;
                    heap.emplace(nd, nx, ny, np);
                }
            }
        }

        ans = min(ans, dist[px][sy][1]);
    }

    cout << ans << "\n";
}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    solve();

    return 0;
}
accuracy: 1
time_ms: 1020
memory_kb: 27976
final_rank: 3

code_snippet: #include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <tuple>
#include <queue>
using namespace std;

namespace{
#define ALL(v) begin(v),end(v)
typedef long long LL;

const LL INF = 1LL << 60;

LL solve(){
	int h, w;
	cin >> h >> w;
	vector<vector<LL>> costs(h, vector<LL>(w));
	int cy = -1, cx = -1;
	for(int i = 0; i < h; ++i)
	for(int j = 0; j < w; ++j){
		cin >> costs[i][j];
		if(costs[i][j] < 0){
			cy = i;
			cx = j;
		}
	}
	
	if(cy * 2 >= h){
		reverse(ALL(costs));
		cy = h - 1 - cy;
	}
	int limk = (cy + 3) / 4;

	const int dd[] = {0, -1, 0, 1, 0};
	LL ans = INF;
	vector<vector<vector<LL>>> dist;
	for(int y0 = 0; y0 < cy; ++y0){
		dist.assign(limk + 1, vector<vector<LL>>(h, vector<LL>(w, INF)));
		priority_queue<tuple<LL,int,int,int>> pq;
		pq.emplace(0, 0, y0, cx);
		dist[0][y0][cx] = 0;
		while(!pq.empty()){
			LL d;
			int k;
			int y, x;
			tie(d, k, y, x) = pq.top();
			pq.pop();
			d = -d;
			if(dist[k][y][x] != d){ continue; }
			if(y == y0 && x == cx && k != 0){
				ans = min(ans, d);
				break;
			}
			for(int i = 0; i < 4; ++i){
				int ny = y + dd[i], nx = x + dd[i + 1];
				if(ny < 0 || ny >= h || nx < 0 || nx >= w){ continue; }
				if(ny == cy && nx == cx){ continue; }
				int nk = k;
				if(ny < cy){
					if(nx == cx - 1 && x == cx){ --nk; }
					else if(x == cx - 1 && nx == cx){ ++nk; }
					if(nk < 0 || nk > limk){ continue; }
				}
				LL nd = d + costs[ny][nx];
				if(dist[nk][ny][nx] > nd){
					dist[nk][ny][nx] = nd;
					pq.emplace(-nd, nk, ny, nx);
				}
			}
		}
	}

	return ans;
}
}
int main(){
	ios::sync_with_stdio(false);
	LL ans = solve();
	cout << ans << '\n';
}
accuracy: 1
time_ms: 380
memory_kb: 31424
final_rank: 2

code_snippet: #include <cmath>
#include <vector>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <algorithm>
#include <set>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <climits>
#include <array>
#include <unordered_set>
#include <unordered_map>
#include <memory>
#include <functional>
#include <cfloat>
#include <numeric>
#include <random>
#include <sstream>
#include <bitset>
#include <complex>
#include <chrono>
#include <cassert>

constexpr int MOD = 1000000007;

std::pair<int, int> find_castle(const std::vector<std::vector<int>>& state) {
	for (auto i = 0; i < state.size(); ++i) {
		for (auto j = 0; j < state[i].size(); ++j) {
			if (state[i][j] < 0) {
				return std::make_pair(i, j);
			}
		}
	}
	throw 0;
}

struct State {
	int x, y; bool left, right;
};
struct MinDistance {
	std::vector<std::vector<std::vector<std::vector<long long int>>>> min_distance;
	MinDistance(const int height, const int width) : min_distance(height, std::vector<std::vector<std::vector<long long int>>>(width, std::vector<std::vector<long long int>>(2, std::vector<long long int>(2, LLONG_MAX)))) {};
	const long long int operator[](const State& state) const {
		return min_distance[state.x][state.y][state.left][state.right];
	}
	long long int& operator[](const State& state) {
		return min_distance[state.x][state.y][state.left][state.right];
	}
};
int main() {
	constexpr std::array<int, 4> diff{ 0, 1, 0, -1 };
	int height, width; std::cin >> height >> width;
	std::vector<std::vector<int>> field_cost(height, std::vector<int>(width));
	for (auto& line : field_cost) {
		for (auto& cell : line) {
			std::cin >> cell;
		}
	}
	const auto [sx, sy] = find_castle(field_cost);
	const auto comparator = [](const std::pair<State, long long int>& a, const std::pair<State, long long int>& b) {return a.second > b.second; };
	std::priority_queue<std::pair<State, long long int>, std::vector<std::pair<State, long long int>>, decltype(comparator)> queue(comparator);
	long long int result{ LLONG_MAX };
	for (auto i = 0; i < height; ++i) {
		if (i == sx) continue;
		MinDistance min_distance(height, width);
		min_distance[State{ i, sy, false, false }] = 0;
		queue.emplace(State{ i, sy, false, false }, 0);
		while (!queue.empty()) {
			const auto [state, cost] = queue.top(); queue.pop();
			if (min_distance[state] < cost) continue;
			for (auto d = 0; d < 4; ++d) {
				const auto dx = diff[d];
				const auto dy = diff[(d + 1) & 3];
				const auto x = state.x + dx;
				const auto y = state.y + dy;
				if (x < 0 || height <= x) continue;
				if (y < 0 || width <= y) continue;
				if (x == sx && y == sy) continue;
				const auto left = (i < sx == x < sx) && ((y == sy && dy == 1) || (state.y == sy && dy == -1)) ? !state.left : state.left;
				const auto right = (i < sx == x < sx) && ((y == sy && dy == -1) || (state.y == sy && dy == 1)) ? !state.right : state.right;
				const State next { x, y, left, right };
				if (min_distance[next] > cost + field_cost[x][y]) {
					min_distance[next] = cost + field_cost[x][y];
					queue.emplace(next, cost + field_cost[x][y]);
				}
			}
		}
		const auto cost = min_distance[State{ i, sy, true, true }];
		result = std::min(result, cost);
	}
	std::cout << result << '\n';
}
accuracy: 1
time_ms: 1880
memory_kb: 42100
final_rank: 5

code_snippet: #include <cmath>
#include <vector>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <algorithm>
#include <set>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <climits>
#include <array>
#include <unordered_set>
#include <unordered_map>
#include <memory>
#include <functional>
#include <cfloat>
#include <numeric>
#include <random>
#include <sstream>
#include <bitset>
#include <complex>
#include <chrono>
#include <cassert>

constexpr int MOD = 1000000007;

std::pair<int, int> find_castle(const std::vector<std::vector<int>>& state) {
	for (auto i = 0; i < state.size(); ++i) {
		for (auto j = 0; j < state[i].size(); ++j) {
			if (state[i][j] < 0) {
				return std::make_pair(i, j);
			}
		}
	}
	throw 0;
}

struct State {
	int x, y; bool up, down, left, right;
};
struct MinDistance {
	std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<long long int>>>>>> min_distance;
	MinDistance(const int height, const int width) : min_distance(height, std::vector<std::vector<std::vector<std::vector<std::vector<long long int>>>>>(width, std::vector<std::vector<std::vector<std::vector<long long int>>>>(2, std::vector<std::vector<std::vector<long long int>>>(2, std::vector<std::vector<long long int>>(2, std::vector<long long int>(2, LLONG_MAX)))))) {};
	const long long int operator[](const State& state) const {
		return min_distance[state.x][state.y][state.up][state.down][state.left][state.right];
	}
	long long int& operator[](const State& state) {
		return min_distance[state.x][state.y][state.up][state.down][state.left][state.right];
	}

};
int main() {
	constexpr std::array<int, 4> diff{ 0, 1, 0, -1 };
	int height, width; std::cin >> height >> width;
	std::vector<std::vector<int>> field_cost(height, std::vector<int>(width));
	for (auto& line : field_cost) {
		for (auto& cell : line) {
			std::cin >> cell;
		}
	}
	const auto [sx, sy] = find_castle(field_cost);
	const auto comparator = [](const std::pair<State, long long int>& a, const std::pair<State, long long int>& b) {return a.second > b.second; };
	std::priority_queue<std::pair<State, long long int>, std::vector<std::pair<State, long long int>>, decltype(comparator)> queue(comparator);
	long long int result{ LLONG_MAX };
	for (auto i = 0; i < height; ++i) {
		if (i == sx) continue;
		MinDistance min_distance(height, width);
		min_distance[State{ i, sy, false, false, false, false }] = 0;
		queue.emplace(State{ i, sy, false, false, false, false }, 0);
		while (!queue.empty()) {
			const auto [state, cost] = queue.top(); queue.pop();
			if (min_distance[state] < cost) continue;
			for (auto d = 0; d < 4; ++d) {
				const auto dx = diff[d];
				const auto dy = diff[(d + 1) & 3];
				const auto x = state.x + dx;
				const auto y = state.y + dy;
				if (x < 0 || height <= x) continue;
				if (y < 0 || height <= y) continue;
				if (x == sx && y == sy) continue;
				const auto up = (y != sy || sx < x || dy == 0) ? state.up : !state.up;
				const auto down = (y != sy || x < sx || dy == 0) ? state.down : !state.down;
				const auto left = (x != sx || sy < y || dx == 0) ? state.left : !state.left;
				const auto right = (x != sx || y < sy || dx == 0) ? state.right : !state.right;
				const State next { x, y, up, down, left, right };
				if (min_distance[next] > cost + field_cost[x][y]) {
					min_distance[next] = cost + field_cost[x][y];
					queue.emplace(next, cost + field_cost[x][y]);
				}
			}
		}
		const auto cost = min_distance[State{ i, sy, true, true, true, true }];
		result = std::min(result, cost);
	}
	std::cout << result << '\n';
}
accuracy: 0.05555555555555555
time_ms: 90
memory_kb: 16144
final_rank: 9

code_snippet: #include <cmath>
#include <vector>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <algorithm>
#include <set>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <climits>
#include <array>
#include <unordered_set>
#include <unordered_map>
#include <memory>
#include <functional>
#include <cfloat>
#include <numeric>
#include <random>
#include <sstream>
#include <bitset>
#include <complex>
#include <chrono>
#include <cassert>

constexpr int MOD = 1000000007;

std::pair<int, int> find_castle(const std::vector<std::vector<int>>& state) {
	for (auto i = 0; i < state.size(); ++i) {
		for (auto j = 0; j < state[i].size(); ++j) {
			if (state[i][j] < 0) {
				return std::make_pair(i, j);
			}
		}
	}
	throw 0;
}
int main() {
	constexpr std::array<int, 4> diff{ 0, 1, 0, -1 };
	int height, width; std::cin >> height >> width;
	std::vector<std::vector<int>> state(height, std::vector<int>(width));
	for (auto& line : state) {
		for (auto& cell : line) {
			std::cin >> cell;
		}
	}
	const auto [x, y] = find_castle(state);
	std::vector<std::vector<std::vector<long long int>>> distance;
	const auto comparator = [](const std::pair<std::pair<int, int>, long long int>& a, const std::pair<std::pair<int, int>, long long int>& b) {return a.second > b.second; };
	std::priority_queue<std::pair<std::pair<int, int>, long long int>, std::vector<std::pair<std::pair<int, int>, long long int>>, decltype(comparator)> queue(comparator);
	for (auto i = 0; i < x; ++i) {
		std::vector<std::vector<long long int>> min_distance(height, std::vector<long long int>(width, LLONG_MAX));
		min_distance[i][y] = 0;
		queue.emplace(std::make_pair(i, y), 0);
		while (!queue.empty()) {
			const auto [current, cost] = queue.top(); queue.pop();
			const auto [r, c] = current;
			if (min_distance[r][c] < cost) continue;
			for (auto d = 0; d < 4; ++d) {
				const auto dr = diff[d];
				const auto dc = diff[(d + 1) & 3];
				const auto nr = r + dr;
				const auto nc = c + dc;
				if (nc == y && nr >= x) continue;
				if (nr < 0 || height <= nr) continue;
				if (nc < 0 || width <= nc) continue;
				if (state[nr][nc] < 0) continue;
				if (min_distance[nr][nc] > cost + state[nr][nc]) {
					min_distance[nr][nc] = cost + state[nr][nc];
					queue.emplace(std::make_pair(nr, nc), min_distance[nr][nc]);
				}
			}
		}
		distance.emplace_back(min_distance);
	}
	distance.emplace_back();
	for (auto i = x + 1; i < height; ++i) {
		std::vector<std::vector<long long int>> min_distance(height, std::vector<long long int>(width, LLONG_MAX));
		min_distance[i][y] = 0;
		queue.emplace(std::make_pair(i, y), 0);
		while (!queue.empty()) {
			const auto [current, cost] = queue.top(); queue.pop();
			const auto [r, c] = current;
			if (min_distance[r][c] < cost) continue;
			for (auto d = 0; d < 4; ++d) {
				const auto dr = diff[d];
				const auto dc = diff[(d + 1) & 3];
				const auto nr = r + dr;
				const auto nc = c + dc;
				if (nc == y && nr <= x) continue;
				if (nr < 0 || height <= nr) continue;
				if (nc < 0 || width <= nc) continue;
				if (state[nr][nc] < 0) continue;
				if (min_distance[nr][nc] > cost + state[nr][nc]) {
					min_distance[nr][nc] = cost + state[nr][nc];
					queue.emplace(std::make_pair(nr, nc), min_distance[nr][nc]);
				}
			}
		}
		distance.emplace_back(min_distance);
	}
	long long int result{ LLONG_MAX };
	for (auto up = 0; up < x; ++up) {
		for (auto down = x + 1; down < height; ++down) {
			long long int left_min{ LLONG_MAX }, right_min{ LLONG_MAX };
			for (auto left = 0; left < y; ++left) {
				const auto cost = distance[up][x][left] + distance[down][x][left] - state[x][left];
				left_min = std::min(left_min, cost);
			}
			for (auto right = y + 1; right < width; ++right) {
				const auto cost = distance[up][x][right] + distance[down][x][right] - state[x][right];
				right_min = std::min(right_min, cost);
			}
			const auto start = state[up][y] + state[down][y];
			const auto cost = left_min + right_min + start;
			result = std::min(result, cost);
		}
	}
	std::cout << result << '\n';
}
accuracy: 0.3333333333333333
time_ms: 350
memory_kb: 36312
final_rank: 6

code_snippet: #include <cmath>
#include <vector>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <algorithm>
#include <set>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <climits>
#include <array>
#include <unordered_set>
#include <unordered_map>
#include <memory>
#include <functional>
#include <cfloat>
#include <numeric>
#include <random>
#include <sstream>
#include <bitset>
#include <complex>
#include <chrono>
#include <cassert>

constexpr int MOD = 1000000007;

std::pair<int, int> find_castle(const std::vector<std::vector<int>>& state) {
	for (auto i = 0; i < state.size(); ++i) {
		for (auto j = 0; j < state[i].size(); ++j) {
			if (state[i][j] < 0) {
				return std::make_pair(i, j);
			}
		}
	}
	throw 0;
}
int main() {
	constexpr std::array<int, 4> diff{ 0, 1, 0, -1 };
	int height, width; std::cin >> height >> width;
	std::vector<std::vector<int>> state(height, std::vector<int>(width));
	for (auto& line : state) {
		for (auto& cell : line) {
			std::cin >> cell;
		}
	}
	const auto [x, y] = find_castle(state);
	std::vector<std::vector<std::vector<long long int>>> distance;
	const auto comparator = [](const std::pair<std::pair<int, int>, long long int>& a, const std::pair<std::pair<int, int>, long long int>& b) {return a.second > b.second; };
	std::priority_queue<std::pair<std::pair<int, int>, long long int>, std::vector<std::pair<std::pair<int, int>, long long int>>, decltype(comparator)> queue(comparator);
	for (auto i = 0; i < x; ++i) {
		std::vector<std::vector<long long int>> min_distance(height, std::vector<long long int>(width, LLONG_MAX));
		min_distance[i][y] = 0;
		queue.emplace(std::make_pair(i, y), 0);
		while (!queue.empty()) {
			const auto [current, cost] = queue.top(); queue.pop();
			const auto [r, c] = current;
			if (min_distance[r][c] < cost) continue;
			for (auto d = 0; d < 4; ++d) {
				const auto dr = diff[d];
				const auto dc = diff[(d + 1) & 3];
				const auto nr = r + dr;
				const auto nc = c + dc;
				if (nc == y && nr < x) continue;
				if (nr < 0 || height <= nr) continue;
				if (nc < 0 || width <= nc) continue;
				if (state[nr][nc] < 0) continue;
				if (min_distance[nr][nc] > cost + state[nr][nc]) {
					min_distance[nr][nc] = cost + state[nr][nc];
					queue.emplace(std::make_pair(nr, nc), min_distance[nr][nc]);
				}
			}
		}
		distance.emplace_back(min_distance);
	}
	distance.emplace_back();
	for (auto i = x + 1; i < height; ++i) {
		std::vector<std::vector<long long int>> min_distance(height, std::vector<long long int>(width, LLONG_MAX));
		min_distance[i][y] = 0;
		queue.emplace(std::make_pair(i, y), 0);
		while (!queue.empty()) {
			const auto [current, cost] = queue.top(); queue.pop();
			const auto [r, c] = current;
			if (min_distance[r][c] < cost) continue;
			for (auto d = 0; d < 4; ++d) {
				const auto dr = diff[d];
				const auto dc = diff[(d + 1) & 3];
				const auto nr = r + dr;
				const auto nc = c + dc;
				if (nc == y && nr > x) continue;
				if (nr < 0 || height <= nr) continue;
				if (nc < 0 || width <= nc) continue;
				if (state[nr][nc] < 0) continue;
				if (min_distance[nr][nc] > cost + state[nr][nc]) {
					min_distance[nr][nc] = cost + state[nr][nc];
					queue.emplace(std::make_pair(nr, nc), min_distance[nr][nc]);
				}
			}
		}
		distance.emplace_back(min_distance);
	}

	long long int result{ LLONG_MAX };
	for (auto up = 0; up < x; ++up) {
		for (auto down = x + 1; down < height; ++down) {
			long long int left_min{ LLONG_MAX }, right_min{ LLONG_MAX };
			for (auto left = 0; left < y; ++left) {
				const auto cost = distance[up][x][left] + distance[down][x][left] - state[x][left];
				left_min = std::min(left_min, cost);
			}
			for (auto right = y + 1; right < width; ++right) {
				const auto cost = distance[up][x][right] + distance[down][x][right] - state[x][right];
				right_min = std::min(right_min, cost);
			}
			const auto start = state[up][y] + state[down][y];
			const auto cost = left_min + right_min + start;
			result = std::min(result, cost);
		}
	}
	std::cout << result << '\n';
}
accuracy: 0.3333333333333333
time_ms: 360
memory_kb: 36404
final_rank: 7

code_snippet: #include <cmath>
#include <vector>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <algorithm>
#include <set>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <climits>
#include <array>
#include <unordered_set>
#include <unordered_map>
#include <memory>
#include <functional>
#include <cfloat>
#include <numeric>
#include <random>
#include <sstream>
#include <bitset>
#include <complex>
#include <chrono>
#include <cassert>

constexpr int MOD = 1000000007;

std::pair<int, int> find_castle(const std::vector<std::vector<int>>& state) {
	for (auto i = 0; i < state.size(); ++i) {
		for (auto j = 0; j < state[i].size(); ++j) {
			if (state[i][j] < 0) {
				return std::make_pair(i, j);
			}
		}
	}
	throw 0;
}
int main() {
	constexpr std::array<int, 4> diff{ 0, 1, 0, -1 };
	int height, width; std::cin >> height >> width;
	std::vector<std::vector<int>> state(height, std::vector<int>(width));
	for (auto& line : state) {
		for (auto& cell : line) {
			std::cin >> cell;
		}
	}
	const auto [x, y] = find_castle(state);
	std::vector<std::vector<std::vector<long long int>>> distance;
	const auto comparator = [](const std::pair<std::pair<int, int>, long long int>& a, const std::pair<std::pair<int, int>, long long int>& b) {return a.second > b.second; };
	std::priority_queue<std::pair<std::pair<int, int>, long long int>, std::vector<std::pair<std::pair<int, int>, long long int>>, decltype(comparator)> queue(comparator);
	for (auto i = 0; i < height; ++i) {
		if (i == x) {
			distance.emplace_back();
			continue;
		}
		std::vector<std::vector<long long int>> min_distance(height, std::vector<long long int>(width, LLONG_MAX));
		min_distance[i][y] = 0;
		queue.emplace(std::make_pair(i, y), 0);
		while (!queue.empty()) {
			const auto [current, cost] = queue.top(); queue.pop();
			const auto [r, c] = current;
			if (min_distance[r][c] < cost) continue;
			for (auto d = 0; d < 4; ++d) {
				const auto dr = diff[d];
				const auto dc = diff[(d + 1) & 3];
				const auto nr = r + dr;
				const auto nc = c + dc;
				if (nr < 0 || height <= nr) continue;
				if (nc < 0 || width <= nc) continue;
				if (state[nr][nc] < 0) continue;
				if (min_distance[nr][nc] > cost + state[nr][nc]) {
					min_distance[nr][nc] = cost + state[nr][nc];
					queue.emplace(std::make_pair(nr, nc), min_distance[nr][nc]);
				}
			}
		}
		distance.emplace_back(min_distance);
	}
	long long int result{ LLONG_MAX };
	for (auto up = 0; up < x; ++up) {
		for (auto down = x + 1; down < height; ++down) {
			long long int left_min{ LLONG_MAX }, right_min{ LLONG_MAX };
			for (auto left = 0; left < y; ++left) {
				const auto cost = distance[up][x][left] + distance[down][x][left] - state[x][left];
				left_min = std::min(left_min, cost);
			}
			for (auto right = y + 1; right < width; ++right) {
				const auto cost = distance[up][x][right] + distance[down][x][right] - state[x][right];
				right_min = std::min(right_min, cost);
			}
			const auto start = state[up][y] + state[down][y];
			const auto cost = left_min + right_min + start;
			result = std::min(result, cost);
		}
	}
	std::cout << result << '\n';
}
accuracy: 0.3333333333333333
time_ms: 350
memory_kb: 36552
final_rank: 8