Problem p00737 (C++)

Buggy submission (status: Runtime Error):
#include <iostream>
#include <queue>
using namespace std;

int W, H;
int inf = 1e9;
int dx[4] = {0, -1, 0, 1}, dy[4] = {1, 0, -1, 0};
int dp[21][21][4] = {};
int S[21][21] = {};
int C[4] = {};

struct state {
  int x, y, direction, dist;
  bool operator<(const state &right) const { return dist > right.dist; }
  void go() {
    x += dx[direction];
    y += dy[direction];
  }
  void turn_right() {
    direction--;
    (direction += 4) %= 4;
    x += dx[direction];
    y += dy[direction];
  }
  void turn_back() {
    (direction += 2) %= 4;
    x += dx[direction];
    y += dy[direction];
  }
  void turn_left() {
    direction++;
    direction %= 4;
    x += dx[direction];
    y += dy[direction];
  }
  void instruction(int i) {
    if (i == 0)
      go();
    if (i == 1)
      turn_right();
    if (i == 2)
      turn_back();
    if (i == 3)
      turn_left();
  }
  bool in() { return 1 <= x && x <= H && 1 <= y && y <= W; }
};

int main() {
  while (cin >> W >> H && W > 0) {
    for (int i = 1; i <= H; i++) {
      for (int j = 1; j <= W; j++) {
        cin >> S[i][j];
        for (int k = 0; k < 4; k++)
          dp[i][j][k] = inf;
      }
    }
    for (int i = 0; i < 4; i++)
      cin >> C[i];
    dp[1][1][0] = 0;
    priority_queue<state> Q;
    state init = {1, 1, 0, 0};
    Q.push(init);
    while (!Q.empty()) {
      state now = Q.top();
      Q.pop();
      if (dp[now.x][now.y][now.direction] < now.dist)
        continue;
      for (int i = 0; i < 4; i++) {
        state ne = now;
        ne.instruction(i);
        int c = now.dist + C[i] * (i != S[now.x][now.y]);
        if (!ne.in())
          continue;
        if (dp[ne.x][ne.y][ne.direction] > c) {
          dp[ne.x][ne.y][ne.direction] = c;
          ne.dist = c;
          Q.push(ne);
        }
      }
    }
    int ans = inf;
    for (int i = 0; i < 4; i++)
      ans = min(ans, dp[H][W][i]);
    cout << ans << endl;
  }
}


Fixed submission:
#include <iostream>
#include <queue>
using namespace std;

int W, H;
int inf = 1e9;
int dx[4] = {0, -1, 0, 1}, dy[4] = {1, 0, -1, 0};
int dp[31][31][4] = {};
int S[31][31] = {};
int C[4] = {};

struct state {
  int x, y, direction, dist;
  bool operator<(const state &right) const { return dist > right.dist; }
  void go() {
    x += dx[direction];
    y += dy[direction];
  }
  void turn_right() {
    direction--;
    (direction += 4) %= 4;
    x += dx[direction];
    y += dy[direction];
  }
  void turn_back() {
    (direction += 2) %= 4;
    x += dx[direction];
    y += dy[direction];
  }
  void turn_left() {
    direction++;
    direction %= 4;
    x += dx[direction];
    y += dy[direction];
  }
  void instruction(int i) {
    if (i == 0)
      go();
    if (i == 1)
      turn_right();
    if (i == 2)
      turn_back();
    if (i == 3)
      turn_left();
  }
  bool in() { return 1 <= x && x <= H && 1 <= y && y <= W; }
};

int main() {
  while (cin >> W >> H && W > 0) {
    for (int i = 1; i <= H; i++) {
      for (int j = 1; j <= W; j++) {
        cin >> S[i][j];
        for (int k = 0; k < 4; k++)
          dp[i][j][k] = inf;
      }
    }
    for (int i = 0; i < 4; i++)
      cin >> C[i];
    dp[1][1][0] = 0;
    priority_queue<state> Q;
    state init = {1, 1, 0, 0};
    Q.push(init);
    while (!Q.empty()) {
      state now = Q.top();
      Q.pop();
      if (dp[now.x][now.y][now.direction] < now.dist)
        continue;
      for (int i = 0; i < 4; i++) {
        state ne = now;
        ne.instruction(i);
        int c = now.dist + C[i] * (i != S[now.x][now.y]);
        if (!ne.in())
          continue;
        if (dp[ne.x][ne.y][ne.direction] > c) {
          dp[ne.x][ne.y][ne.direction] = c;
          ne.dist = c;
          Q.push(ne);
        }
      }
    }
    int ans = inf;
    for (int i = 0; i < 4; i++)
      ans = min(ans, dp[H][W][i]);
    cout << ans << endl;
  }
}