Problem p00731 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include "bits/stdc++.h"
using namespace std;
#ifdef _DEBUG
#include "dump.hpp"
#else
#define dump(...)
#endif

// #define int long long
#define rep(i, a, b) for (int i = (a); i < (b); i++)
#define rrep(i, a, b) for (int i = (b)-1; i >= (a); i--)
#define all(c) begin(c), end(c)
const int INF =
    sizeof(int) == sizeof(long long) ? 0x3f3f3f3f3f3f3f3fLL : 0x3f3f3f3f;
const int MOD = (int)(1e9) + 7;
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return true;
  }
  return false;
}

using Weight = int;
using Flow = int;
struct Edge {
  int s, d;
  Weight w;
  Flow c;
  Edge(){};
  Edge(int s, int d, Weight w = 1) : s(s), d(d), w(w), c(w){};
};
bool operator<(const Edge &e1, const Edge &e2) { return e1.w < e2.w; }
bool operator>(const Edge &e1, const Edge &e2) { return e2 < e1; }
inline ostream &operator<<(ostream &os, const Edge &e) {
  return (os << '(' << e.s << ", " << e.d << ", " << e.w << ')');
}

using Edges = vector<Edge>;
using Graph = vector<Edges>;
using Array = vector<Weight>;
using Matrix = vector<Array>;

void addArc(Graph &g, int s, int d, Weight w = 1) {
  g[s].emplace_back(s, d, w);
}
void addEdge(Graph &g, int a, int b, Weight w = 1) {
  addArc(g, a, b, w);
  addArc(g, b, a, w);
}

vector<int> dijkstra(const Graph &g, int s, Array &dist) {
  int n = g.size();
  assert(s < n);
  enum { WHITE, GRAY, BLACK };
  vector<int> color(n, WHITE);
  color[s] = GRAY;
  vector<int> prev(n, -1);
  dist.assign(n, INF);
  dist[s] = 0;
  using State = tuple<Weight, int, int>;
  priority_queue<State, vector<State>, greater<State>> pq;
  pq.emplace(0, s, -1);
  while (pq.size()) {
    Weight d;
    int v, u;
    tie(d, v, u) = pq.top();
    pq.pop();
    if (dist[v] < d)
      continue;
    color[v] = BLACK;
    prev[v] = u;
    for (auto &e : g[v]) {
      if (color[e.d] == BLACK)
        continue;
      if (dist[e.d] > dist[v] + e.w) {
        dist[e.d] = dist[v] + e.w;
        pq.emplace(dist[e.d], e.d, v);
        color[e.d] = GRAY;
      }
    }
  }
  return prev;
}

//??§?¨???§???
// index()??¨??????????????????
template <typename T> vector<T> compress(vector<T> v) {
  sort(v.begin(), v.end());
  v.erase(unique(v.begin(), v.end()), v.end());
  return v;
}

signed main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  for (int w, h; cin >> w >> h && h;) {
    vector<vector<char>> c(h, vector<char>(w));
    rep(i, 0, h) rep(j, 0, w) cin >> c[i][j];
    auto inrange = [&](int i, int j) {
      return i >= 0 && i < h && j >= 0 && j < w;
    };
    auto valid = [&](int li, int lj, int ri, int rj) {
      return abs(li - ri) + abs(lj - rj) <= 3 && lj < rj;
    };
    auto idx = [&](int li, int lj, int ri, int rj, int right) {
      int ret = li;
      ret *= w;
      ret += lj;
      ret *= h;
      ret += ri;
      ret *= w;
      ret += rj;
      ret += (w * h * w * h) * right;
      return ret;
    };

    vector<int> v;
    rep(li, 0, h) rep(lj, 0, w) rep(ri, 0, h) rep(rj, 0, w) {
      if (valid(li, lj, ri, rj)) {
        v.push_back(idx(li, lj, ri, rj, 0));
        v.push_back(idx(li, lj, ri, rj, 1));
      }
    }
    vector<int> zip = compress(v);

    auto index = [&](int li, int lj, int ri, int rj, int r) {
      return lower_bound(zip.begin(), zip.end(), idx(li, lj, ri, rj, r)) -
             zip.begin();
    };
    Graph g(zip.size() + 2);
    // next right 1
    int s = zip.size(), t = s + 1;

    rep(li, 0, h) rep(lj, 0, w) rep(ri, 0, h) rep(rj, lj + 1, w) {
      if (!valid(li, lj, ri, rj))
        continue;
      // dump(li, lj, ri, rj);
      if (c[li][lj] == 'X' || c[ri][rj] == 'X')
        continue;
      if (c[li][lj] == 'S') {
        addArc(g, s, index(li, lj, ri, rj, 0),
               c[ri][rj] == 'S' ? 0 : c[ri][rj] - '0');
      }
      if (c[ri][rj] == 'S') {
        addArc(g, s, index(li, lj, ri, rj, 1),
               c[li][lj] == 'S' ? 0 : c[li][lj] - '0');
      }
      if (c[li][lj] == 'T') {
        addArc(g, index(li, lj, ri, rj, 1), t, 0);
      }
      if (c[ri][rj] == 'T') {
        addArc(g, index(li, lj, ri, rj, 0), t, 0);
      }
      rep(r, 0, 2) {
        int u = index(li, lj, ri, rj, r);
        rep(di, -10, 10) rep(dj, -10, 10) {
          int nli = li, nlj = lj, nri = ri, nrj = rj;
          int cost;
          if (r) {
            nri += di;
            nrj += dj;
            if (!inrange(nri, nrj))
              continue;
            if (c[nri][nrj] == 'X')
              continue;
            cost = c[nri][nrj] == 'T' ? 0 : c[nri][nrj] - '0';
          } else {
            nli += di;
            nlj += dj;
            if (!inrange(nli, nlj))
              continue;
            if (c[nli][nlj] == 'X')
              continue;
            cost = c[nli][nlj] == 'T' ? 0 : c[nli][nlj] - '0';
          }
          if (!valid(nli, nlj, nri, nrj))
            continue;
          // dump(nli, nlj, nri, nrj);
          int v = index(nli, nlj, nri, nrj, !r);
          addArc(g, u, v, cost);
        }
      }
    }
    int ans = INF;
    Array dist;
    dijkstra(g, s, dist);
    chmin(ans, dist[t]);
    cout << (ans == INF ? -1 : ans) << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

#include "bits/stdc++.h"
using namespace std;
#ifdef _DEBUG
#include "dump.hpp"
#else
#define dump(...)
#endif

// #define int long long
#define rep(i, a, b) for (int i = (a); i < (b); i++)
#define rrep(i, a, b) for (int i = (b)-1; i >= (a); i--)
#define all(c) begin(c), end(c)
const int INF =
    sizeof(int) == sizeof(long long) ? 0x3f3f3f3f3f3f3f3fLL : 0x3f3f3f3f;
const int MOD = (int)(1e9) + 7;
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return true;
  }
  return false;
}

using Weight = int;
using Flow = int;
struct Edge {
  int s, d;
  Weight w;
  Flow c;
  Edge(){};
  Edge(int s, int d, Weight w = 1) : s(s), d(d), w(w), c(w){};
};
bool operator<(const Edge &e1, const Edge &e2) { return e1.w < e2.w; }
bool operator>(const Edge &e1, const Edge &e2) { return e2 < e1; }
inline ostream &operator<<(ostream &os, const Edge &e) {
  return (os << '(' << e.s << ", " << e.d << ", " << e.w << ')');
}

using Edges = vector<Edge>;
using Graph = vector<Edges>;
using Array = vector<Weight>;
using Matrix = vector<Array>;

void addArc(Graph &g, int s, int d, Weight w = 1) {
  g[s].emplace_back(s, d, w);
}
void addEdge(Graph &g, int a, int b, Weight w = 1) {
  addArc(g, a, b, w);
  addArc(g, b, a, w);
}

vector<int> dijkstra(const Graph &g, int s, Array &dist) {
  int n = g.size();
  assert(s < n);
  enum { WHITE, GRAY, BLACK };
  vector<int> color(n, WHITE);
  color[s] = GRAY;
  vector<int> prev(n, -1);
  dist.assign(n, INF);
  dist[s] = 0;
  using State = tuple<Weight, int, int>;
  priority_queue<State, vector<State>, greater<State>> pq;
  pq.emplace(0, s, -1);
  while (pq.size()) {
    Weight d;
    int v, u;
    tie(d, v, u) = pq.top();
    pq.pop();
    if (dist[v] < d)
      continue;
    color[v] = BLACK;
    prev[v] = u;
    for (auto &e : g[v]) {
      if (color[e.d] == BLACK)
        continue;
      if (dist[e.d] > dist[v] + e.w) {
        dist[e.d] = dist[v] + e.w;
        pq.emplace(dist[e.d], e.d, v);
        color[e.d] = GRAY;
      }
    }
  }
  return prev;
}

signed main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  for (int w, h; cin >> w >> h && h;) {
    vector<vector<char>> c(h, vector<char>(w));
    rep(i, 0, h) rep(j, 0, w) cin >> c[i][j];
    auto inrange = [&](int i, int j) {
      return i >= 0 && i < h && j >= 0 && j < w;
    };
    auto valid = [&](int li, int lj, int ri, int rj) {
      return abs(li - ri) + abs(lj - rj) <= 3 && lj < rj;
    };
    auto index = [&](int li, int lj, int ri, int rj, int right) {
      int ret = li;
      ret *= w;
      ret += lj;
      ret *= h;
      ret += ri;
      ret *= w;
      ret += rj;
      ret += (w * h * w * h) * right;
      return ret;
    };
    // next right 1
    Graph g(h * w * h * w * 2 + 2);
    int s = h * w * h * w * 2, t = s + 1;
    rep(li, 0, h) rep(lj, 0, w) rep(ri, 0, h) rep(rj, lj + 1, w) {
      if (!valid(li, lj, ri, rj))
        continue;
      // dump(li, lj, ri, rj);
      if (c[li][lj] == 'X' || c[ri][rj] == 'X')
        continue;
      if (c[li][lj] == 'S') {
        addArc(g, s, index(li, lj, ri, rj, 0),
               c[ri][rj] == 'S' ? 0 : c[ri][rj] - '0');
      }
      if (c[ri][rj] == 'S') {
        addArc(g, s, index(li, lj, ri, rj, 1),
               c[li][lj] == 'S' ? 0 : c[li][lj] - '0');
      }
      if (c[li][lj] == 'T') {
        addArc(g, index(li, lj, ri, rj, 1), t, 0);
      }
      if (c[ri][rj] == 'T') {
        addArc(g, index(li, lj, ri, rj, 0), t, 0);
      }
      rep(r, 0, 2) {
        int u = index(li, lj, ri, rj, r);
        rep(di, -10, 10) rep(dj, -10, 10) {
          int nli = li, nlj = lj, nri = ri, nrj = rj;
          int cost;
          if (r) {
            nri += di;
            nrj += dj;
            if (!inrange(nri, nrj))
              continue;
            if (c[nri][nrj] == 'X')
              continue;
            cost = c[nri][nrj] == 'T' ? 0 : c[nri][nrj] - '0';
          } else {
            nli += di;
            nlj += dj;
            if (!inrange(nli, nlj))
              continue;
            if (c[nli][nlj] == 'X')
              continue;
            cost = c[nli][nlj] == 'T' ? 0 : c[nli][nlj] - '0';
          }
          if (!valid(nli, nlj, nri, nrj))
            continue;
          // dump(nli, nlj, nri, nrj);
          int v = index(nli, nlj, nri, nrj, !r);
          addArc(g, u, v, cost);
        }
      }
    }
    int ans = INF;
    Array dist;
    dijkstra(g, s, dist);
    chmin(ans, dist[t]);
    cout << (ans == INF ? -1 : ans) << endl;
  }
  return 0;
}