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

#include <algorithm>
#include <cmath>
#include <iostream>
#include <queue>
using namespace std;
#define INF (1 << 28)
typedef pair<int, int> P;
struct state {
  int ay, ax, by, bx, f, cost;
  bool operator<(const state &p) const { return cost > p.cost; }
};
int W, H;
int t[60][30];
vector<P> A, B;

void init() {
  A.clear();
  B.clear();
}

int dist(int a, int b, int c, int d) { return abs(a - c) + abs(b - d); }
int d[60][30][60][30][2];
int solve() {
  fill((int *)d, (int *)(d + 60), INF);
  sort(A.begin(), A.end());
  sort(B.begin(), B.end());
  state s;
  priority_queue<state> Q;
  for (int i = 0; i < (int)A.size(); i++) {
    s.ay = A[i].second;
    s.ax = A[i].first;
    s.by = A[i].second;
    s.bx = A[i].first;
    s.cost = 0;
    for (int j = 0; j < 2; j++) {
      s.f = j;
      d[s.ay][s.ax][s.by][s.bx][s.f] = 0;
      Q.push(s);
    }
  }
  while (!Q.empty()) {
    s = Q.top();
    Q.pop();
    if (s.cost > d[s.ay][s.ax][s.by][s.bx][s.f])
      continue;
    if (t[s.ay][s.ax] == 0 || t[s.by][s.bx] == 0)
      return s.cost;

    for (int i = -4; i <= 4; i++) {
      for (int j = -4; j <= 4; j++) {
        state w = s;
        int ny, nx;
        if (s.f)
          ny = w.ay + i, nx = w.ax + j;
        else
          ny = w.by + i, nx = w.bx + j;
        if (ny < 0 || nx < 0)
          continue;
        if (ny >= H || nx >= W)
          continue;
        if (s.f)
          w.ay = ny, w.ax = nx;
        else
          w.by = ny, w.bx = nx;
        w.f = 1 - s.f;
        w.cost = s.cost + t[ny][nx];
        if (w.bx >= w.ax)
          continue;
        if (dist(w.ay, w.ax, w.by, w.bx) > 3)
          continue;
        if (w.cost > d[w.ay][w.ax][w.by][w.bx][w.f])
          continue;
        d[w.ay][w.ax][w.by][w.bx][w.f] = w.cost;
        Q.push(w);
      }
    }
  }
  return -1;
}

int main() {
  while (1) {
    cin >> W >> H;
    if (W == 0 && H == 0)
      break;
    init();
    char ch;
    for (int i = 0; i < H; i++) {
      for (int j = 0; j < W; j++) {
        cin >> ch;
        t[i][j] = INF;
        if (ch == 'S')
          A.push_back(P(j, i));
        else if (ch == 'T')
          t[i][j] = 0;
        else if ('0' <= ch && ch <= '9')
          t[i][j] = ch - '0';
      }
    }
    cout << solve() << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
using namespace std;
#define INF (1 << 28)
typedef pair<int, int> P;
struct state {
  vector<P> pos;
  int cost;
  bool operator<(const state &p) const { return cost > p.cost; }
};
int W, H;
int t[60][30];
map<vector<P>, int> d;
vector<P> A, B;

void init() {
  A.clear();
  B.clear();
  d.clear();
}

int dist(P a, P b) { return abs(a.first - b.first) + abs(a.second - b.second); }

int solve() {
  P sl = min(A[0], A[1]), sr = max(A[0], A[1]);
  P tl = min(B[0], B[1]), tr = max(B[0], B[1]);
  vector<P> vec(3);
  vec[0] = sl;
  vec[1] = sr;
  vec[2] = P(0, 0);
  state s = (state){vec, 1};
  priority_queue<state> Q;
  Q.push(s);
  d[s.pos] = 1;
  s.pos[2].first = 1;
  Q.push(s);
  d[s.pos] = 1;

  swap(s.pos[0], s.pos[1]);
  Q.push(s);
  d[s.pos] = 1;
  s.pos[2].first = 1;
  Q.push(s);
  d[s.pos] = 1;

  while (!Q.empty()) {
    state s = Q.top();
    Q.pop();
    if (s.cost > d[s.pos])
      continue;

    /*
    cout<<s.pos[0].first<<" "<<s.pos[0].second<<endl;
    cout<<s.pos[1].first<<" "<<s.pos[1].second<<endl;
    cout<<s.cost<<endl;
    */
    if (s.pos[0] == tl || s.pos[1] == tr)
      return s.cost - 1;
    if (s.pos[1] == tl || s.pos[0] == tr)
      return s.cost - 1;
    int f = s.pos[2].first;

    for (int i = -4; i <= 4; i++) {
      for (int j = -4; j <= 4; j++) {
        state next = s;
        int nx = s.pos[1 - f].first + i;
        int ny = s.pos[1 - f].second + j;
        if (i == 0 && j == 0)
          continue;
        if (nx < 0 || ny < 0)
          continue;
        if (nx >= W || ny >= H)
          continue;
        if (t[ny][nx] == INF)
          continue;
        next.pos[f].first = nx;
        next.pos[f].second = ny;
        next.pos[2].first = 1 - f;
        next.cost = s.cost + t[ny][nx];
        if (next.pos[1].first <= next.pos[0].first)
          continue;
        if (dist(next.pos[0], next.pos[1]) > 3)
          continue;
        if (d[next.pos] == 0)
          d[next.pos] = INF;
        if (next.cost >= d[next.pos])
          continue;

        d[next.pos] = next.cost;
        Q.push(next);
      }
    }
  }
  return -1;
}

int main() {
  while (1) {
    cin >> W >> H;
    if (W == 0 && H == 0)
      break;
    init();
    char ch;
    for (int i = 0; i < H; i++) {
      for (int j = 0; j < W; j++) {
        cin >> ch;
        t[i][j] = 0;
        if (ch == 'X')
          t[i][j] = INF;
        else if (ch == 'S')
          A.push_back(P(j, i));
        else if (ch == 'T')
          B.push_back(P(j, i));
        else
          t[i][j] = ch - '0';
      }
    }
    cout << solve() << endl;
  }
  return 0;
}