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

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

typedef vector<int> vi;
typedef vector<vi> vvi;

const int MAX_V = 3600;
const int INF = 9999999;

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

int cost[MAX_V][MAX_V];
int d[MAX_V];
bool used[MAX_V];
int V;

int h, w;

bool in(int i, int j) { return 0 <= i && i < h && 0 <= j && j < w; }

int toV(int i, int j, int dir) { return 4 * (i * w + j) + dir; }

void calc() {
  fill(d, d + V, INF);
  fill(used, used + V, false);
  d[0] = 0;

  while (true) {
    int v = -1;
    for (int u = 0; u < V; u++) {
      if (!used[u] && (v == -1 || d[u] < d[v]))
        v = u;
    }

    if (v == -1)
      break;
    used[v] = true;
    for (int u = 0; u < V; u++) {
      d[u] = min(d[u], d[v] + cost[v][u]);
    }
  }
}

int main() {
  while (cin >> w >> h, w != 0 || h != 0) {
    vvi s = vvi(h, vi(w, 0));
    for (int i = 0; i < h; i++)
      for (int j = 0; j < w; j++)
        cin >> s[i][j];
    int c[4];
    for (int i = 0; i < 4; i++)
      cin >> c[i];

    for (int i = 0; i < MAX_V; i++)
      for (int j = 0; j < MAX_V; j++)
        cost[i][j] = INF;

    V = 4 * w * h;

    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        for (int dir = 0; dir < 4; dir++) {
          cost[toV(i, j, dir)][toV(i, j, dir)] = 0;
          for (int ndir = 0; ndir < 4; ndir++) {
            int ni = i + dy[ndir], nj = j + dx[ndir];
            if (!in(ni, nj))
              continue;
            if (s[i][j] != 4 && (dir + s[i][j]) % 4 == ndir)
              cost[toV(i, j, dir)][toV(ni, nj, ndir)] = 0;
            else
              cost[toV(i, j, dir)][toV(ni, nj, ndir)] = c[(ndir - dir + 4) % 4];
          }
        }
      }
    }

    calc();

    int ans = INF;
    for (int dir = 0; dir < 4; dir++) {
      ans = min(ans, d[toV(h - 1, w - 1, dir)]);
    }

    cout << ans << endl;
  }
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

typedef vector<int> vi;
typedef vector<vi> vvi;

const int MAX_V = 4000;
const int INF = 9999999;

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

vvi cost;
int d[MAX_V];
bool used[MAX_V];
int V;

int h, w;

bool in(int i, int j) { return 0 <= i && i < h && 0 <= j && j < w; }

int toV(int i, int j, int dir) { return 4 * (i * w + j) + dir; }

void calc() {
  fill(d, d + V, INF);
  fill(used, used + V, false);
  d[0] = 0;

  while (true) {
    int v = -1;
    for (int u = 0; u < V; u++) {
      if (!used[u] && (v == -1 || d[u] < d[v]))
        v = u;
    }

    if (v == -1)
      break;
    used[v] = true;
    for (int u = 0; u < V; u++) {
      d[u] = min(d[u], d[v] + cost[v][u]);
    }
  }
}

int main() {
  while (cin >> w >> h, w != 0 || h != 0) {
    vvi s = vvi(h, vi(w, 0));
    for (int i = 0; i < h; i++)
      for (int j = 0; j < w; j++)
        cin >> s[i][j];
    int c[4];
    for (int i = 0; i < 4; i++)
      cin >> c[i];

    V = 4 * w * h;
    cost = vvi(V, vi(V, INF));
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        for (int dir = 0; dir < 4; dir++) {
          cost[toV(i, j, dir)][toV(i, j, dir)] = 0;
          for (int ndir = 0; ndir < 4; ndir++) {
            int ni = i + dy[ndir], nj = j + dx[ndir];
            if (!in(ni, nj))
              continue;
            if (s[i][j] != 4 && (dir + s[i][j]) % 4 == ndir)
              cost[toV(i, j, dir)][toV(ni, nj, ndir)] = 0;
            else
              cost[toV(i, j, dir)][toV(ni, nj, ndir)] = c[(ndir - dir + 4) % 4];
          }
        }
      }
    }

    calc();

    int ans = INF;
    for (int dir = 0; dir < 4; dir++) {
      ans = min(ans, d[toV(h - 1, w - 1, dir)]);
    }

    cout << ans << endl;
  }
}