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

#include <bits/stdc++.h>
using namespace std;

#define REP(i, n) for (int i = 0; i < n; i++)
#define rep(i, n) for (int i = 0; i < n; i++)
#define INF 1 << 29
#define LINF LLONG_MAX / 3
#define MP make_pair
#define PB push_back
#define EB emplace_back
#define ALL(v) (v).begin(), (v).end()
#define all(v) ALL(v)
#define debug(x) cerr << #x << ":" << x << endl
#define debug2(x, y) cerr << #x << "," << #y ":" << x << "," << y << endl
#define CININIT cin.tie(0), ios::sync_with_stdio(false)
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
  os << "[";
  for (const auto &v : vec) {
    os << v << ",";
  }
  os << "]";
  return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << "(" << p.first << "," << p.second << ")";
  return os;
}
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
ll gcd(ll a, ll b) {
  if (b == 0)
    return a;
  else
    return gcd(b, a % b);
}

constexpr ll mod = 1e9 + 7;
const int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};

int h, w;

class Node {
public:
  int cost, x, y, pre;
  Node() {}
  Node(int a, int b, int c, int d) {
    cost = a;
    x = b;
    y = c;
    pre = d;
  }

  bool operator<(const Node &nd) const { return cost < nd.cost; }
  bool operator>(const Node &nd) const { return cost > nd.cost; }
  bool operator==(const Node &nd) const { return cost == nd.cost; }

  void print() const {
    printf("Node : cost(%d) , (x,y)=(%d,%d), pre=%d\\n", cost, x, y, pre);
  }
};

int move(int dir, int m) {
  if (m == 0) {
    return dir;
  } else if (m == 1) {
    return (dir + 1) % 4;
  } else if (m == 2) {
    return (dir + 2) % 4;
  } else if (m == 3) {
    return (dir - 1 + 4) % 4;
  } else {
    assert(false);
  }
  return -1;
}

void solve() {
  using P = tuple<int, int, int, int>;
  vvi s(h, vi(w));
  vi c(4);
  rep(i, h) rep(j, w) cin >> s[i][j];
  rep(i, 4) cin >> c[i];

  int d[32][32][5];
  rep(i, 32) rep(j, 32) rep(k, 5) d[i][j][k] = INF;

  priority_queue<Node, vector<Node>, greater<Node>> que;
  que.push(Node(0, 0, 0, 0));
  while (!que.empty()) {
    Node p = que.top();
    que.pop();
    int cost = p.cost, x = p.x, y = p.y, pre = p.pre;

    if (x == h - 1 and y == w - 1) {
      cout << cost << endl;
      return;
    }

    rep(i, 4) {
      int ndir = move(pre, i);
      int nx = x + dx[ndir];
      int ny = y + dy[ndir];
      if (nx < 0 or nx >= h or ny < 0 or ny >= w)
        continue;

      if (i == s[x][y]) {
        if (cost < d[nx][ny][ndir]) {
          d[nx][ny][ndir] = cost;
          que.push(Node(cost, nx, ny, ndir));
        }
      } else {
        if (cost + c[i] < d[nx][ny][ndir]) {
          d[nx][ny][ndir] = cost + c[i];
          que.push(Node(cost + c[i], nx, ny, ndir));
        }
      }
    }
  }
}

int main() {
  while (cin >> w >> h) {
    if (h == 0 and w == 0)
      break;
    solve();
  }
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

#define REP(i, n) for (int i = 0; i < n; i++)
#define rep(i, n) for (int i = 0; i < n; i++)
#define INF 1 << 29
#define LINF LLONG_MAX / 3
#define MP make_pair
#define PB push_back
#define EB emplace_back
#define ALL(v) (v).begin(), (v).end()
#define all(v) ALL(v)
#define debug(x) cerr << #x << ":" << x << endl
#define debug2(x, y) cerr << #x << "," << #y ":" << x << "," << y << endl
#define CININIT cin.tie(0), ios::sync_with_stdio(false)
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
  os << "[";
  for (const auto &v : vec) {
    os << v << ",";
  }
  os << "]";
  return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << "(" << p.first << "," << p.second << ")";
  return os;
}
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
ll gcd(ll a, ll b) {
  if (b == 0)
    return a;
  else
    return gcd(b, a % b);
}

constexpr ll mod = 1e9 + 7;
const int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};

int h, w;

class Node {
public:
  int cost, x, y, pre;
  Node() {}
  Node(int a, int b, int c, int d) {
    cost = a;
    x = b;
    y = c;
    pre = d;
  }

  bool operator<(const Node &nd) const { return cost < nd.cost; }
  bool operator>(const Node &nd) const { return cost > nd.cost; }
  bool operator==(const Node &nd) const { return cost == nd.cost; }

  void print() const {
    printf("Node : cost(%d) , (x,y)=(%d,%d), pre=%d\\n", cost, x, y, pre);
  }
};

int move(int dir, int m) {
  if (m == 0) {
    return dir;
  } else if (m == 1) {
    return (dir + 1) % 4;
  } else if (m == 2) {
    return (dir + 2) % 4;
  } else if (m == 3) {
    return (dir - 1 + 4) % 4;
  } else {
    assert(false);
  }
  return -1;
}

void solve() {
  using P = tuple<int, int, int, int>;
  vvi s(h, vi(w));
  vi c(4);
  rep(i, h) rep(j, w) cin >> s[i][j];
  rep(i, 4) cin >> c[i];
  //    rep(i,h){
  //        rep(j,w) cout << s[i][j];
  //        cout << endl;
  //    }
  //    cout << c << endl;

  int d[32][32][5];
  rep(i, 32) rep(j, 32) rep(k, 5) d[i][j][k] = INF;

  priority_queue<Node, vector<Node>, greater<Node>> que;
  que.push(Node(0, 0, 0, 0));
  while (!que.empty()) {
    Node p = que.top();
    que.pop();
    int cost = p.cost, x = p.x, y = p.y, pre = p.pre;

    if (x == h - 1 and y == w - 1) {
      cout << cost << endl;
      return;
    }

    rep(i, 4) {
      int ndir = move(pre, i);
      int nx = x + dx[ndir];
      int ny = y + dy[ndir];
      if (nx < 0 or nx >= h or ny < 0 or ny >= w)
        continue;

      if (i == s[x][y]) {
        if (cost < d[nx][ny][ndir]) {
          d[nx][ny][ndir] = cost;
          que.push(Node(cost, nx, ny, ndir));
        }
      } else {
        if (cost < d[nx][ny][ndir]) {
          d[nx][ny][ndir] = cost + c[i];
          que.push(Node(cost + c[i], nx, ny, ndir));
        }
      }
    }
  }
}

int main() {
  while (cin >> w >> h) {
    if (h == 0 and w == 0)
      break;
    solve();
  }
}