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

/*
    脳がない
 */

#include <cassert>
#include <cstdio>
#include <queue>
#include <utility>
using namespace std;

#define LEFT 0
#define RIGHT 1
#define INF 0x3fffffff

typedef pair<int, int> Coor;
typedef pair<int, Coor> Data;
typedef pair<int, Data> Pair;

int w;
int h;
int ans;
bool is_goal[60][30];
int cost[60][30];
int lmin[60][30];
int rmin[60][30];

int main() {
  while (1) {
    queue<Pair> q;

    scanf("%d%d", &w, &h);
    if (w == 0 && h == 0)
      return 0;

    ans = INF;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        lmin[i][j] = INF;
        rmin[i][j] = INF;
      }
    }

    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        char c;

        is_goal[i][j] = false;
        scanf(" %c", &c);
        if (c == 'X') {
          cost[i][j] = INF;
        } else if (c == 'S') {
          cost[i][j] = 0;
          lmin[i][j] = 0;
          rmin[i][j] = 0;
          q.push(Pair(0, Data(LEFT, Coor(j, i))));
          q.push(Pair(0, Data(RIGHT, Coor(j, i))));
        } else if (c == 'T') {
          cost[i][j] = 0;
          is_goal[i][j] = true;
        } else {
          cost[i][j] = c - '0';
          assert(1 <= cost[i][j] && cost[i][j] <= 9);
        }
      }
    }

    while (!q.empty()) {
      Pair p = q.front();
      q.pop();
      int dist = p.first;
      Data d = p.second;
      int last = d.first;
      Coor c = d.second;
      int x = c.first;
      int y = c.second;

      if (last == LEFT && dist > lmin[y][x])
        continue;
      if (last == RIGHT && dist > rmin[y][x])
        continue;

      if (last == LEFT) {
        for (int i = 2; i >= 0; i--) {
          for (int j = -i; j <= i; j++) {
            int _x = x + 3 - i;
            int _y = y + j;

            if (_x < 0 || w <= _x)
              continue;
            if (_y < 0 || h <= _y)
              continue;
            if (cost[_y][_x] == INF)
              continue;

            if (rmin[_y][_x] > dist + cost[_y][_x]) {
              rmin[_y][_x] = dist + cost[_y][_x];
              if (is_goal[_y][_x]) {
                ans = min(ans, rmin[_y][_x]);
                continue;
              }
              q.push(Pair(rmin[_y][_x], Data(RIGHT, Coor(_x, _y))));
            }
          }
        }
      } else {
        for (int i = 2; i >= 0; i--) {
          for (int j = -i; j <= i; j++) {
            int _x = x - (3 - i);
            int _y = y + j;

            if (_x < 0 || w <= _x)
              continue;
            if (_y < 0 || h <= _y)
              continue;
            if (cost[_y][_x] == INF)
              continue;

            if (lmin[_y][_x] > dist + cost[_y][_x]) {
              lmin[_y][_x] = dist + cost[_y][_x];
              if (is_goal[_y][_x]) {
                ans = min(ans, lmin[_y][_x]);
                continue;
              }
              q.push(Pair(lmin[_y][_x], Data(LEFT, Coor(_x, _y))));
            }
          }
        }
      }
    }

    if (ans < INF) {
      printf("%d\\n", ans);
    } else {
      puts("-1");
    }
  }
}

Error: TLE

Fixed submission:

#include <cassert>
#include <cstdio>
#include <queue>
#include <utility>
using namespace std;

#define LEFT 0
#define RIGHT 1
#define INF 0x60000000

typedef pair<int, int> Coor;
typedef pair<int, Coor> Data;
typedef pair<int, Data> Pair;

int w;
int h;
int ans;
bool is_goal[60][30];
int cost[60][30];
int lmin[60][30];
int rmin[60][30];

int main() {
  while (1) {
    priority_queue<Pair> q;

    scanf("%d%d", &w, &h);
    if (w == 0 && h == 0)
      return 0;

    ans = INF;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        lmin[i][j] = INF;
        rmin[i][j] = INF;
      }
    }

    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        char c;

        is_goal[i][j] = false;
        scanf(" %c", &c);
        if (c == 'X') {
          cost[i][j] = INF;
        } else if (c == 'S') {
          cost[i][j] = 0;
          lmin[i][j] = 0;
          rmin[i][j] = 0;
          q.push(Pair(0, Data(LEFT, Coor(j, i))));
          q.push(Pair(0, Data(RIGHT, Coor(j, i))));
        } else if (c == 'T') {
          cost[i][j] = 0;
          is_goal[i][j] = true;
        } else {
          cost[i][j] = c - '0';
          assert(1 <= cost[i][j] && cost[i][j] <= 9);
        }
      }
    }

    while (!q.empty()) {
      Pair p = q.top();
      q.pop();
      int dist = p.first;
      Data d = p.second;
      int last = d.first;
      Coor c = d.second;
      int x = c.first;
      int y = c.second;

      if (last == LEFT && dist > lmin[y][x])
        continue;
      if (last == RIGHT && dist > rmin[y][x])
        continue;

      if (last == LEFT) {
        for (int i = 2; i >= 0; i--) {
          for (int j = -i; j <= i; j++) {
            int _x = x + 3 - i;
            int _y = y + j;

            if (_x < 0 || w <= _x)
              continue;
            if (_y < 0 || h <= _y)
              continue;

            if (rmin[_y][_x] > dist + cost[_y][_x]) {
              rmin[_y][_x] = dist + cost[_y][_x];
              if (is_goal[_y][_x]) {
                ans = min(ans, rmin[_y][_x]);
                continue;
              }
              q.push(Pair(rmin[_y][_x], Data(RIGHT, Coor(_x, _y))));
            }
          }
        }
      } else {
        for (int i = 2; i >= 0; i--) {
          for (int j = -i; j <= i; j++) {
            int _x = x - (3 - i);
            int _y = y + j;

            if (_x < 0 || w <= _x)
              continue;
            if (_y < 0 || h <= _y)
              continue;

            if (lmin[_y][_x] > dist + cost[_y][_x]) {
              lmin[_y][_x] = dist + cost[_y][_x];
              if (is_goal[_y][_x]) {
                ans = min(ans, lmin[_y][_x]);
                continue;
              }
              q.push(Pair(lmin[_y][_x], Data(LEFT, Coor(_x, _y))));
            }
          }
        }
      }
    }

    if (ans < INF) {
      printf("%d\\n", ans);
    } else {
      puts("-1");
    }
  }
}