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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;
int main() {
  int i, j;
  int w, h;
  while (cin >> w >> h, w || h) {
    int a[36][64];
    memset(a, -1, sizeof(a));
    for (i = 2; i < h + 2; i++) {
      for (j = 3; j < w + 3; j++) {
        char s;
        cin >> s;
        if (0) {
        } else if (s == 'S') {
          a[j][i] = 0;
        } else if (s == 'T') {
          a[j][i] = 0;
        } else if (s == 'X') {
          a[j][i] = -1;
        } else {
          a[j][i] = s - '0';
        }
      }
    }
    int b[36][66][2];
    memset(b, -1, sizeof(b));
    priority_queue<pair<pair<int, int>, pair<int, int>>,
                   vector<pair<pair<int, int>, pair<int, int>>>,
                   greater<pair<pair<int, int>, pair<int, int>>>>
        c;
    for (i = 3; i < w + 3; i++) {
      if (a[i][h + 1] == 0) {
        c.push(make_pair(make_pair(0, 0), make_pair(i, h + 1)));
        c.push(make_pair(make_pair(0, 1), make_pair(i, h + 1)));
      }
    }
    while (c.empty() == 0) {
      int v, w, x, y;
      v = c.top().first.first;
      w = c.top().first.second;
      x = c.top().second.first;
      y = c.top().second.second;
      if (y == 2 && a[x][y] == 0)
        break;
      c.pop();
      if (b[x][y][w] == -1 || b[x][y][w] > v) {
        b[x][y][w] = v;
        if (w) {
          int p, q;
          p = x - 1;
          q = y;
          if (a[p][q] != -1)
            c.push(make_pair(make_pair(v + a[p][q], 0), make_pair(p, q)));
          p = x - 2;
          q = y;
          if (a[p][q] != -1)
            c.push(make_pair(make_pair(v + a[p][q], 0), make_pair(p, q)));
          p = x - 3;
          q = y;
          if (a[p][q] != -1)
            c.push(make_pair(make_pair(v + a[p][q], 0), make_pair(p, q)));
          p = x - 1;
          q = y + 1;
          if (a[p][q] != -1)
            c.push(make_pair(make_pair(v + a[p][q], 0), make_pair(p, q)));
          p = x - 2;
          q = y + 1;
          if (a[p][q] != -1)
            c.push(make_pair(make_pair(v + a[p][q], 0), make_pair(p, q)));
          p = x - 1;
          q = y - 1;
          if (a[p][q] != -1)
            c.push(make_pair(make_pair(v + a[p][q], 0), make_pair(p, q)));
          p = x - 2;
          q = y - 1;
          if (a[p][q] != -1)
            c.push(make_pair(make_pair(v + a[p][q], 0), make_pair(p, q)));
          p = x - 1;
          q = y + 2;
          if (a[p][q] != -1)
            c.push(make_pair(make_pair(v + a[p][q], 0), make_pair(p, q)));
          p = x - 1;
          q = y - 2;
          if (a[p][q] != -1)
            c.push(make_pair(make_pair(v + a[p][q], 0), make_pair(p, q)));
        } else {
          int p, q;
          p = x + 1;
          q = y;
          if (a[p][q] != -1)
            c.push(make_pair(make_pair(v + a[p][q], 1), make_pair(p, q)));
          p = x + 2;
          q = y;
          if (a[p][q] != -1)
            c.push(make_pair(make_pair(v + a[p][q], 1), make_pair(p, q)));
          p = x + 3;
          q = y;
          if (a[p][q] != -1)
            c.push(make_pair(make_pair(v + a[p][q], 1), make_pair(p, q)));
          p = x + 1;
          q = y + 1;
          if (a[p][q] != -1)
            c.push(make_pair(make_pair(v + a[p][q], 1), make_pair(p, q)));
          p = x + 2;
          q = y + 1;
          if (a[p][q] != -1)
            c.push(make_pair(make_pair(v + a[p][q], 1), make_pair(p, q)));
          p = x + 1;
          q = y - 1;
          if (a[p][q] != -1)
            c.push(make_pair(make_pair(v + a[p][q], 1), make_pair(p, q)));
          p = x + 2;
          q = y - 1;
          if (a[p][q] != -1)
            c.push(make_pair(make_pair(v + a[p][q], 1), make_pair(p, q)));
          p = x + 1;
          q = y + 2;
          if (a[p][q] != -1)
            c.push(make_pair(make_pair(v + a[p][q], 1), make_pair(p, q)));
          p = x + 1;
          q = y - 2;
          if (a[p][q] != -1)
            c.push(make_pair(make_pair(v + a[p][q], 1), make_pair(p, q)));
        }
      }
    }
    cout << (c.empty() ? -1 : c.top().first.first) << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <string>
using namespace std;
int a[36][64], q = 0;
short b[2][36][64][36][64];
int fn(int, int, int, int);
int gn(int, int, int, int);
int fn(int lx, int ly, int rx, int ry) {
  int mn = 30000;
  if (0) {
  } else if (a[lx][ly] == -1) {
  } else if (a[lx][ly] == -2) {
    mn = q;
  } else {
    q += a[lx][ly];
    if (b[1][lx][ly][rx][ry] > q) {
      b[1][lx][ly][rx][ry] = q;
      mn = min(mn, gn(lx, ly, lx + 1, ly - 2));
      mn = min(mn, gn(lx, ly, lx + 1, ly - 1));
      mn = min(mn, gn(lx, ly, lx + 1, ly));
      mn = min(mn, gn(lx, ly, lx + 1, ly + 1));
      mn = min(mn, gn(lx, ly, lx + 1, ly + 2));
      mn = min(mn, gn(lx, ly, lx + 2, ly - 1));
      mn = min(mn, gn(lx, ly, lx + 2, ly));
      mn = min(mn, gn(lx, ly, lx + 2, ly + 1));
      mn = min(mn, gn(lx, ly, lx + 3, ly));
    }
    q -= a[lx][ly];
  }
  return mn;
}
int gn(int lx, int ly, int rx, int ry) {
  int mn = 30000;
  if (0) {
  } else if (a[rx][ry] == -1) {
  } else if (a[rx][ry] == -2) {
    mn = q;
  } else {
    q += a[rx][ry];
    if (b[0][lx][ly][rx][ry] > q) {
      b[0][lx][ly][rx][ry] = q;
      mn = min(mn, fn(rx - 1, ry - 2, rx, ry));
      mn = min(mn, fn(rx - 1, ry - 1, rx, ry));
      mn = min(mn, fn(rx - 1, ry, rx, ry));
      mn = min(mn, fn(rx - 1, ry + 1, rx, ry));
      mn = min(mn, fn(rx - 1, ry + 2, rx, ry));
      mn = min(mn, fn(rx - 2, ry - 1, rx, ry));
      mn = min(mn, fn(rx - 2, ry, rx, ry));
      mn = min(mn, fn(rx - 2, ry + 1, rx, ry));
      mn = min(mn, fn(rx - 3, ry, rx, ry));
    }
    q -= a[rx][ry];
  }
  return mn;
}
int main() {
  int i, j, k, l;
  int x[30], y[30], n, w, h;
  int mn;
  char s;
  while (cin >> w >> h && w + h) {
    memset(a, -1, sizeof(a));
    n = 0;
    for (i = 2; i < h + 2; i++) {
      for (j = 3; j < w + 3; j++) {
        cin >> s;
        if (0) {
        } else if (s == 'S') {
          a[j][i] = 0;
          x[n] = j;
          y[n] = i;
          n++;
        } else if (s == 'T') {
          a[j][i] = -2;
        } else if (s == 'X') {
        } else {
          a[j][i] = s - '0';
        }
      }
    }
    for (i = 0; i < w + 6; i++) {
      for (j = 0; j < h + 4; j++) {
        for (k = 0; k < w + 6; k++) {
          for (l = 0; l < h + 4; l++) {
            b[0][i][j][k][l] = 30000;
            b[1][i][j][k][l] = 30000;
          }
        }
      }
    }
    mn = 30000;
    for (i = 0; i < n; i++) {
      mn = min(mn, fn(x[i], y[i], x[i], y[i]));
      mn = min(mn, gn(x[i], y[i], x[i], y[i]));
    }
    if (mn == 30000)
      cout << -1 << endl;
    else
      cout << mn << endl;
  }
  return 0;
}