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

#include <cstdio>
#include <iostream>
#include <queue>
using namespace std;
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rep1(i, n) for (int i = 1; i <= (n); ++i)
#define all(c) (c).begin(), (c).end()
typedef pair<int, int> P;
int dw[2][9] = {{1, 1, 1, 1, 1, 2, 2, 2, 3},
                {-1, -1, -1, -1, -1, -2, -2, -2, -3}};
int dh[2][9] = {{-2, -1, 0, 1, 2, -1, 0, 1, 0}, {-2, -1, 0, 1, 2, -1, 0, 1, 0}};
char mp[61][31];
int dis[2][60][30];
int w, h, ans;
void dijkstra(int si, int sj, int sk) {
  rep(i, 2) rep(j, h) rep(k, w) dis[i][j][k] = 1e+8;
  dis[si][sj][sk] = 0;
  priority_queue<P, vector<P>, greater<P>> que;
  que.push(P(0, si * h * w + sj * w + sk));
  while (!que.empty()) {
    P p = que.top();
    que.pop();
    int vs = p.second;
    int vi = vs / (h * w), vj = (vs / w) % h, vk = vs % w;
    if (dis[vi][vj][vk] < p.first)
      continue;
    rep(i, 9) {
      int nj = vj + dh[vi][i], nk = vk + dw[vi][i], ni = 1 - vi;
      if (0 <= nj && nj < h && 0 <= nk && nk < w && mp[nj][nk] != 'X' &&
          mp[nj][nk] != 'S') {
        int &dn = dis[ni][nj][nk], &dv = dis[vi][vj][vk], cost = 0;
        if (mp[nj][nk] != 'T')
          cost = mp[nj][nk] - '0';
        if (dn > dv + cost) {
          dn = dv + cost;
          que.push(P(dn, ni * h * w + nj * w + nk));
        }
      }
    }
  }
  rep(j, w) if (mp[0][j] == 'T') rep(i, 2) ans = min(ans, dis[i][0][j]);
}
int main() {
  while (true) {
    scanf("%d%d", &w, &h);
    if (w == 0)
      break;
    ans = 1e+8;
    rep(i, h) rep(j, w) scanf(" %c", &mp[i][j]);
    rep(j, w) if (mp[h - 1][j] == 'S') rep(i, 2) dijkstra(i, h - 1, j);
    if (ans == 1e8)
      ans = -1;
    printf("%d\\n", ans);
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <cstdio>
#include <iostream>
using namespace std;
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rep1(i, n) for (int i = 1; i <= (n); ++i)
#define all(c) (c).begin(), (c).end()
int dw[2][9] = {{1, 1, 1, 1, 1, 2, 2, 2, 3},
                {-1, -1, -1, -1, -1, -2, -2, -2, -3}};
int dh[2][9] = {{-2, -1, 0, 1, 2, -1, 0, 1, 0}, {-2, -1, 0, 1, 2, -1, 0, 1, 0}};
char mp[61][31];
int dis[2][60][30];
bool used[2][60][30];
int w, h, ans;
void dijkstra(int si, int sj, int sk) {
  rep(i, 2) rep(j, h) rep(k, w) dis[i][j][k] = 1e+8, used[i][j][k] = false;
  dis[si][sj][sk] = 0;
  while (true) {
    int vi = -1, vj = -1, vk = -1;
    rep(i, 2) rep(j, h) rep(k, w) {
      if (!used[i][j][k] && mp[j][k] != 'X' &&
          (vi == -1 || dis[i][j][k] < dis[vi][vj][vk]))
        vi = i, vj = j, vk = k;
    }
    if (vi == -1)
      break;
    used[vi][vj][vk] = true;
    rep(i, 9) {
      int nj = vj + dh[vi][i], nk = vk + dw[vi][i], ni = 1 - vi;
      if (0 <= nj && nj < h && 0 <= nk && nk < w && mp[nj][nk] != 'X' &&
          mp[nj][nk] != 'S') {
        if (mp[nj][nk] == 'T')
          dis[ni][nj][nk] = min(dis[ni][nj][nk], dis[vi][vj][vk]);
        dis[ni][nj][nk] =
            min(dis[ni][nj][nk], dis[vi][vj][vk] + (mp[nj][nk] - '0'));
      }
    }
  }
  rep(j, w) if (mp[0][j] == 'T') rep(i, 2) ans = min(ans, dis[i][0][j]);
}
int main() {
  while (true) {
    scanf("%d%d", &w, &h);
    if (w == 0)
      break;
    ans = 1e+8;
    rep(i, h) rep(j, w) scanf(" %c", &mp[i][j]);
    rep(j, w) if (mp[h - 1][j] == 'S') rep(i, 2) dijkstra(i, h - 1, j);
    if (ans == 1e8)
      ans = -1;
    printf("%d\\n", ans);
  }
  return 0;
}