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

#include <algorithm>
#include <climits>
#include <functional>
#include <iostream>
#include <queue>
#include <tuple>
#include <vector>
using namespace std;

typedef tuple<int, int, int> Point;
typedef tuple<int, Point> Node;
int Next[2][9][2] = {
    {{-2, 1}, {-1, 1}, {0, 1}, {1, 1}, {2, 1}, {-1, 2}, {0, 2}, {1, 2}, {0, 3}},
    {{-2, -1},
     {-1, -1},
     {0, -1},
     {1, -1},
     {2, -1},
     {-1, -2},
     {0, -2},
     {1, -2},
     {0, -3}},

};
enum { LEFT, RIGHT };
enum { Y, X, SIDE };
enum { COST, POINT };
enum { START = -2, TOP, NIL };

int Dijkstra(const vector<vector<int>> &cliff, const Point &start) {
  int result = INT_MAX;
  int h = cliff.size();
  int w = cliff.front().size();
  vector<vector<vector<int>>> cost(
      h, vector<vector<int>>(w, vector<int>(2, INT_MAX)));
  priority_queue<Node, vector<Node>, greater<Node>> q;
  q.push(Node(0, start));
  while (!q.empty()) {
    int c = get<COST>(q.top());
    Point point = get<POINT>(q.top());
    q.pop();
    if (cost[get<Y>(point)][get<X>(point)][get<SIDE>(point)] != INT_MAX)
      continue;
    cost[get<Y>(point)][get<X>(point)][get<SIDE>(point)] = c;
    for (const auto &d : Next[get<SIDE>(point)]) {
      int y = get<Y>(point) + d[Y];
      int x = get<X>(point) + d[X];
      if (y < 0 || h <= y)
        continue;
      if (x < 0 || w <= x)
        continue;
      if (cliff[y][x] == NIL)
        continue;
      if (cliff[y][x] == START)
        continue;
      if (cliff[y][x] == TOP) {
        result = min(result, c);
      } else {
        Point next_point(y, x, get<SIDE>(point) ^ 1);
        q.push(Node(c + cliff[y][x], next_point));
      }
    }
  }
  return result;
}

int main() {
  int w, h;
  while (cin >> w >> h, w | h) {
    vector<vector<int>> cliff(h, vector<int>(w));
    for (auto &line : cliff)
      for (auto &v : line) {
        char c;
        cin >> c;
        if (c == 'S')
          v = START;
        else if (c == 'T')
          v = TOP;
        else if (c == 'X')
          v = NIL;
        else
          v = c - '0';
      }

    int answer = INT_MAX;
    for (int y = 0; y < h; y++)
      for (int x = 0; x < w; x++) {
        if (cliff[y][x] != START)
          continue;
        answer = min({answer, Dijkstra(cliff, Point(y, x, LEFT)),
                      Dijkstra(cliff, Point(y, x, RIGHT))});
      }
    cout << ((answer == INT_MAX) ? -1 : answer) << endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <climits>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <tuple>
#include <vector>
using namespace std;

typedef tuple<int, int, int> Point;
typedef tuple<int, Point> Node;
int Next[2][9][2] = {
    {{-2, 1}, {-1, 1}, {0, 1}, {1, 1}, {2, 1}, {-1, 2}, {0, 2}, {1, 2}, {0, 3}},
    {{-2, -1},
     {-1, -1},
     {0, -1},
     {1, -1},
     {2, -1},
     {-1, -2},
     {0, -2},
     {1, -2},
     {0, -3}},

};
enum { LEFT, RIGHT };
enum { Y, X, SIDE };
enum { COST, POINT };
enum { START = -2, TOP, NIL };

int Dijkstra(const vector<vector<int>> &cliff, const Point &start) {
  int result = INT_MAX;
  int h = cliff.size();
  int w = cliff.front().size();
  map<Point, int> cost;
  priority_queue<Node, vector<Node>, greater<Node>> q;
  q.push(Node(0, start));
  while (!q.empty()) {
    int c = get<COST>(q.top());
    Point point = get<POINT>(q.top());
    q.pop();
    if (cost.count(point))
      continue;
    cost[point] = c;
    for (const auto &d : Next[get<SIDE>(point)]) {
      int y = get<Y>(point) + d[Y];
      int x = get<X>(point) + d[X];
      if (y < 0 || h <= y)
        continue;
      if (x < 0 || w <= x)
        continue;
      if (cliff[y][x] == NIL)
        continue;
      if (cliff[y][x] == START)
        continue;
      if (cliff[y][x] == TOP) {
        result = min(result, c);
      } else {
        Point next_point(y, x, get<SIDE>(point) ^ 1);
        q.push(Node(c + cliff[y][x], next_point));
      }
    }
  }
  return result;
}

int main() {
  int w, h;
  while (cin >> w >> h, w | h) {
    vector<vector<int>> cliff(h, vector<int>(w));
    for (auto &line : cliff)
      for (auto &v : line) {
        char c;
        cin >> c;
        if (c == 'S')
          v = START;
        else if (c == 'T')
          v = TOP;
        else if (c == 'X')
          v = NIL;
        else
          v = c - '0';
      }

    int answer = INT_MAX;
    for (int y = 0; y < h; y++)
      for (int x = 0; x < w; x++) {
        if (cliff[y][x] != START)
          continue;
        answer = min({answer, Dijkstra(cliff, Point(y, x, LEFT)),
                      Dijkstra(cliff, Point(y, x, RIGHT))});
      }
    cout << ((answer == INT_MAX) ? -1 : answer) << endl;
  }
}