Problem p02670 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << "(" << p.first << "," << p.second << ")";
  return os;
}
#ifdef __LOCAL
#define debug(x) cerr << __LINE__ << ": " << #x << " = " << (x) << endl
#define debugArray(x, n)                                                       \
  cerr << __LINE__ << ": " << #x << " = {";                                    \
  for (long long hoge = 0; (hoge) < (long long)(n); ++(hoge))                  \
    cerr << ((hoge) ? "," : "") << x[hoge];                                    \
  cerr << "}" << endl
#else
#define debug(x) (void(0))
#define debugArray(x, n) (void(0))
#endif

signed main() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  int N;
  cin >> N;
  int P[N * N];
  for (int i = 0; i < N * N; i++)
    cin >> P[i], P[i]--;
  auto node = [&](int i, int j) { return N * i + j; };
  auto ij = [&](int v) { return make_pair(v / N, v % N); };
  pair<int, int> dir[4] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
  int cost[N * N];
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      cost[node(i, j)] = min({i + 1, N - i, j + 1, N - j});
    }
  }
  bool rem[N * N];
  fill(rem, rem + N * N, true);
  // debugArray(cost, N * N);
  int ans = 0;
  for (int p : P) {
    rem[p] = false;
    queue<pair<int, int>> que;
    int pc = cost[p];
    int pci, pcj;
    tie(pci, pcj) = ij(p);
    for (int d = 0; d < 4; d++) {
      int ni = pci + dir[d].first, nj = pcj + dir[d].second;
      int c = 0;
      if (!(ni < 0 || N <= ni || nj < 0 || N <= nj))
        c = cost[node(ni, nj)];
      if (pc > c + rem[p]) {
        pc = c + rem[p];
      }
    }
    que.push({p, pc});
    while (!que.empty()) {
      int v, c;
      tie(v, c) = que.front();
      que.pop();
      if (cost[v] < c)
        continue;
      cost[v] = c;
      int ci, cj;
      tie(ci, cj) = ij(v);
      for (int d = 0; d < 4; d++) {
        int ni = ci + dir[d].first, nj = cj + dir[d].second;
        if (ni < 0 || N <= ni || nj < 0 || N <= nj)
          continue;
        int next = node(ni, nj);
        if (cost[next] > cost[v] + rem[next])
          que.push({next, cost[v] + rem[next]});
      }
    }
    ans += cost[p];
    // debugArray(cost, N * N);
  }

  cout << ans << '\n';
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << "(" << p.first << "," << p.second << ")";
  return os;
}
#ifdef __LOCAL
#define debug(x) cerr << __LINE__ << ": " << #x << " = " << (x) << endl
#define debugArray(x, n)                                                       \
  cerr << __LINE__ << ": " << #x << " = {";                                    \
  for (long long hoge = 0; (hoge) < (long long)(n); ++(hoge))                  \
    cerr << ((hoge) ? "," : "") << x[hoge];                                    \
  cerr << "}" << endl
#else
#define debug(x) (void(0))
#define debugArray(x, n) (void(0))
#endif

signed main() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  int N;
  cin >> N;
  int P[N * N];
  for (int i = 0; i < N * N; i++)
    cin >> P[i], P[i]--;
  auto node = [&](int i, int j) { return N * i + j; };
  auto ij = [&](int v) { return make_pair(v / N, v % N); };
  pair<int, int> dir[4] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
  int cost[N * N];
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      cost[node(i, j)] = min({i + 1, N - i, j + 1, N - j});
    }
  }
  bool rem[N * N];
  fill(rem, rem + N * N, true);
  // debugArray(cost, N * N);
  int ans = 0;
  for (int p : P) {
    rem[p] = false;
    queue<pair<int, int>> que;
    int pc = cost[p];
    int pci, pcj;
    tie(pci, pcj) = ij(p);
    for (int d = 0; d < 4; d++) {
      int ni = pci + dir[d].first, nj = pcj + dir[d].second;
      int c = 0;
      if (!(ni < 0 || N <= ni || nj < 0 || N <= nj))
        c = cost[node(ni, nj)];
      if (pc > c + rem[p]) {
        pc = c + rem[p];
      }
    }
    que.push({p, pc});
    while (!que.empty()) {
      int v, c;
      tie(v, c) = que.front();
      que.pop();
      if (cost[v] <= c)
        continue;
      cost[v] = c;
      int ci, cj;
      tie(ci, cj) = ij(v);
      for (int d = 0; d < 4; d++) {
        int ni = ci + dir[d].first, nj = cj + dir[d].second;
        if (ni < 0 || N <= ni || nj < 0 || N <= nj)
          continue;
        int next = node(ni, nj);
        if (cost[next] > cost[v] + rem[next])
          que.push({next, cost[v] + rem[next]});
      }
    }
    ans += cost[p];
    // debugArray(cost, N * N);
  }

  cout << ans << '\n';
  return 0;
}