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

#include <algorithm>
#include <iostream>
#include <queue>
#define N_MAX 30
#define INF (1e9)
using namespace std;
void dijkstra();
int w, h, data[N_MAX][N_MAX], d[N_MAX][N_MAX][4], c[4];
int dy[4] = {-1, 0, 1, 0};
int dx[4] = {0, 1, 0, -1};
typedef struct stu {
  int mincost, y, x, dir;
  bool operator<(const stu &right) const { return mincost > right.mincost; }
} dat;

int main() {
  while (1) {
    cin >> w >> h;
    if (!w && !h)
      break;
    for (int i = 0; i < h; i++)
      for (int j = 0; j < w; j++)
        cin >> data[i][j];
    for (int i = 0; i < 4; i++)
      cin >> c[i];
    dijkstra();
  }
  return 0;
}

void dijkstra() {
  priority_queue<dat> Q;
  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++)
      for (int k = 0; k < 4; k++)
        d[i][j][k] = INF;
  d[0][0][1] = 0;
  Q.push((dat){0, 0, 0, 1});
  while (!Q.empty()) {
    dat t = Q.top();
    Q.pop();
    int cost = t.mincost, y = t.y, x = t.x, dir = t.dir;
    if (cost > d[y][x][dir])
      continue;
    for (int i = 0; i < 4; i++) {
      int ny = y + dy[(dir + i) % 4], nx = x + dx[(dir + i) % 4];
      int ndir = (dir + i) % 4;
      if (ny < 0 || nx < 0 || h <= ny || w <= nx)
        continue;
      if (d[ny][nx][ndir] > cost + c[i]) {
        d[ny][nx][ndir] = cost + c[i];
        Q.push((dat){d[ny][nx][ndir], ny, nx, ndir});
      }
      if (data[y][x] != i)
        continue;
      if (d[ny][nx][ndir] > cost) {
        d[ny][nx][ndir] = cost;
        Q.push((dat){d[ny][nx][ndir], ny, nx, ndir});
      }
    }
  }
  int mincost = INF;
  for (int i = 0; i < 4; i++)
    mincost = min(mincost, d[h - 1][w - 1][i]);
  cout << mincost << endl;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <queue>
#define N_MAX 30
#define INF (1e9)
using namespace std;
void dijkstra();
int w, h, data[N_MAX][N_MAX], d[N_MAX][N_MAX][4], c[4];
int dy[4] = {-1, 0, 1, 0};
int dx[4] = {0, 1, 0, -1};
typedef struct stu {
  int mincost, y, x, dir;
  bool operator<(const stu &right) const { return mincost < right.mincost; }
} dat;

int main() {
  while (1) {
    cin >> w >> h;
    if (!w && !h)
      break;
    for (int i = 0; i < h; i++)
      for (int j = 0; j < w; j++)
        cin >> data[i][j];
    for (int i = 0; i < 4; i++)
      cin >> c[i];
    dijkstra();
  }
  return 0;
}

void dijkstra() {
  priority_queue<dat> Q;
  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++)
      for (int k = 0; k < 4; k++)
        d[i][j][k] = INF;
  d[0][0][1] = 0;
  Q.push((dat){0, 0, 0, 1});
  while (!Q.empty()) {
    dat t = Q.top();
    Q.pop();
    int cost = t.mincost, y = t.y, x = t.x, dir = t.dir;
    if (cost < d[y][x][dir])
      continue;
    for (int i = 0; i < 4; i++) {
      int ny = y + dy[(dir + i) % 4], nx = x + dx[(dir + i) % 4];
      int ndir = (dir + i) % 4;
      if (ny < 0 || nx < 0 || h <= ny || w <= nx)
        continue;
      if (d[ny][nx][ndir] > cost + c[i]) {
        d[ny][nx][ndir] = cost + c[i];
        Q.push((dat){d[ny][nx][ndir], ny, nx, ndir});
      }
      if (data[y][x] != i)
        continue;
      if (d[ny][nx][ndir] > cost) {
        d[ny][nx][ndir] = cost;
        Q.push((dat){d[ny][nx][ndir], ny, nx, ndir});
      }
    }
  }
  int mincost = INF;
  for (int i = 0; i < 4; i++)
    mincost = min(mincost, d[h - 1][w - 1][i]);
  cout << mincost << endl;
}