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

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

class node {
public:
  int cost, x, y, d;
  node(int _cost, int _x, int _y, int _d) {
    cost = _cost;
    x = _x;
    y = _y;
    d = _d;
  }
  bool operator>(const node &s) const { return cost > s.cost; }
};

int main() {
  int dx[] = {0, 1, 0, -1};
  int dy[] = {-1, 0, 1, 0};
  while (true) {
    int w, h;
    cin >> w >> h;
    if (w == 0 && h == 0) {
      break;
    }

    int field[w][h];
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        cin >> field[j][i];
      }
    }
    int d[4];
    for (int i = 0; i < 4; i++) {
      cin >> d[i];
    }

    int memo[w][h][4];
    memset(memo, -1, sizeof(memo));
    memo[0][0][1] = 0;
    priority_queue<node, vector<node>, greater<node>> pque;
    pque.push(node(0, 0, 0, 1));
    while (!pque.empty()) {
      node p = pque.top();
      pque.pop();

      for (int i = 0; i < 4; i++) {
        int nd = (i + p.d) % 4;
        int nx = p.x + dx[nd];
        int ny = p.y + dy[nd];

        if (nx < 0 || ny < 0 || nx >= w || ny >= h) {
          continue;
        }
        if (field[p.x][p.y] == i) {
          if (memo[nx][ny][nd] == -1 ||
              memo[nx][ny][nd] > memo[p.x][p.y][p.d]) {
            memo[nx][ny][nd] = memo[p.x][p.y][p.d];
            pque.push(node(memo[nx][ny][nd], nx, ny, nd));
          }
        } else {
          if (memo[nx][ny][nd] == -1 ||
              memo[nx][ny][nd] > memo[p.x][p.y][p.d] + d[i]) {
            memo[nx][ny][nd] = memo[p.x][p.y][p.d] + d[i];
            pque.push(node(memo[nx][ny][nd], nx, ny, nd));
          }
        }
      }
    }

    std::cout << min(memo[w - 1][h - 1][1], memo[w - 1][h - 1][2]) << std::endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstring>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

#define STRAIGHT 0
#define RIGHT 1
#define BACK 2
#define LEFT 3
#define HALT 4

#define NORTH 0
#define EAST 1
#define SOUTH 2
#define WEST 3

int memo[30][30][4];
int c[4];
int field[30][30];
int dx[] = {0, 1, 0, -1};
int dy[] = {-1, 0, 1, 0};
int h, w;
void rec(int x, int y, int dir) {
  for (int i = 0; i < 4; i++) { // iは命令
    int p = (i + dir) % 4;      // マップ上の向き
    int nx = x + dx[p];
    int ny = y + dy[p];
    if (nx < 0 || ny < 0 || nx >= w || ny >= h)
      continue;
    if (field[x][y] == i &&
        (memo[nx][ny][p] == -1 || memo[nx][ny][p] > memo[x][y][dir])) {
      memo[nx][ny][p] = memo[x][y][dir];
      rec(nx, ny, p);
    } else if (memo[nx][ny][p] == -1 ||
               memo[nx][ny][p] > memo[x][y][dir] + c[i]) {
      memo[nx][ny][p] = memo[x][y][dir] + c[i];
      rec(nx, ny, p);
    }
  }
}

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

    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        int s;
        cin >> s;
        if (s == STRAIGHT) {
          field[j][i] = STRAIGHT;
        } else if (s == RIGHT) {
          field[j][i] = RIGHT;
        } else if (s == BACK) {
          field[j][i] = BACK;
        } else if (s == LEFT) {
          field[j][i] = LEFT;
        } else {
          field[j][i] = HALT;
        }
      }
    }

    // for (int i = 0; i < h; i++) {
    //   for (int j = 0; j < w; j++) {
    // 	std::cout << field[j][i] << " ";
    //   }
    //   std::cout << "" << std::endl;
    // }

    for (int i = 0; i < 4; i++) {
      cin >> c[i];
    }

    memset(memo, -1, sizeof(memo));
    memo[0][0][RIGHT] = 0;
    rec(0, 0, RIGHT);
    // for (int i = 0; i < h; i++) {
    //   for (int j = 0; j < w; j++) {
    // 	std::cout << memo[j][i][LEFT] << " ";
    //   }
    //   std::cout << "" << std::endl;
    // }

    int ans = min(memo[w - 1][h - 1][EAST], memo[w - 1][h - 1][SOUTH]);

    std::cout << ans << std::endl;
  }
}