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

#include "bits/stdc++.h"

#define REP(i, n) for (int i = 0; i < (n); i++)
#define REPR(i, n) for (int i = (n); i >= 0; i--)
#define FOR(i, m, n) for (int i = (m); i < (n); i++)
#define FORR(i, m, n) for (int i = (m); i >= (n); i--)
#define SORT(v, n) std::sort(v, v + n);
#define VSORT(v) std::sort(v.begin(), v.end());
#define VRSORT(v) std::sort(v.rbegin(), v.rend());
#define ll long long
#define pb(a) push_back(a)
#define ALL(obj) (obj).begin(), (obj).end()

using namespace std;

const int INF = 99999999;
const ll LINF = 9999999999999;

typedef pair<ll, ll> LP;
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

char S[1010][1010] = {};
ll cost_map[1010][1010] = {};
ll ch, cw, dh, dw, H, W;

void dfs(ll w, ll h, ll cost) {

  deque<tuple<ll, ll, ll>> uncalced;
  uncalced.emplace_back(make_tuple(w, h, cost));

  while (!uncalced.empty()) {
    tuple<ll, ll, ll> state = uncalced.front();
    uncalced.pop_front();
    w = get<0>(state);
    h = get<1>(state);
    cost = get<2>(state);

    cost_map[w][h] = cost;
    if (w == dw && h == dh)
      return;

    // 普通に移動
    if (w + 1 < W && cost_map[w + 1][h] > cost && S[w + 1][h] == '.')
      uncalced.emplace_front(make_tuple(
          w + 1, h, cost)); // マス目に移動でき、コストが小さくできる余地がある
    if (w > 0 && cost_map[w - 1][h] > cost && S[w - 1][h] == '.')
      uncalced.emplace_front(make_tuple(w - 1, h, cost));
    if (h + 1 < H && cost_map[w][h + 1] > cost && S[w][h + 1] == '.')
      uncalced.emplace_front(make_tuple(w, h + 1, cost));
    if (h < H && cost_map[w][h - 1] > cost && S[w][h - 1] == '.')
      uncalced.emplace_front(make_tuple(w, h - 1, cost));

    // ワープ移動
    REP(i, 5) {
      REP(j, 5) {
        int movew = i - 2;
        int moveh = j - 2;
        if (w + movew < W && w + movew >= 0 && h + moveh < H &&
            h + moveh >= 0 && cost_map[w + movew][h + moveh] > cost + 1 &&
            S[w + movew][h + moveh] == '.')
          uncalced.emplace_back(make_tuple(w + movew, h + moveh, cost + 1));
      }
    }
  }
}

int main() {

  cin >> H >> W >> ch >> cw >> dh >> dw;
  ch--;
  cw--;
  dh--;
  dw--;
  REP(j, H) {
    REP(i, W) {
      cin >> S[i][j];
      cost_map[i][j] = LINF;
    }
  }

  dfs(cw, ch, 0);

  if (cost_map[dw][dh] == LINF) {
    cout << -1 << endl;
  } else {
    cout << cost_map[dw][dh];
  }

  return 0;
}


Error: TLE

Fixed submission:

#include "bits/stdc++.h"

#define REP(i, n) for (int i = 0; i < (n); i++)
#define REPR(i, n) for (int i = (n); i >= 0; i--)
#define FOR(i, m, n) for (int i = (m); i < (n); i++)
#define FORR(i, m, n) for (int i = (m); i >= (n); i--)
#define SORT(v, n) std::sort(v, v + n);
#define VSORT(v) std::sort(v.begin(), v.end());
#define VRSORT(v) std::sort(v.rbegin(), v.rend());
#define ll long long
#define pb(a) push_back(a)
#define ALL(obj) (obj).begin(), (obj).end()

using namespace std;

const int INF = 99999999;
const ll LINF = 9999999999999;

typedef pair<ll, ll> LP;
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

char S[1010][1010] = {};
ll cost_map[1010][1010] = {};
ll ch, cw, dh, dw, H, W;

void dfs(ll w, ll h, ll cost) {

  vector<tuple<ll, ll, ll>> uncalced;
  uncalced.push_back(make_tuple(w, h, cost));

  while (!uncalced.empty()) {
    tuple<ll, ll, ll> state =
        uncalced.back(); // 積んである最後尾の配列を読む（取り出されない）
    uncalced.pop_back();
    w = get<0>(state);
    h = get<1>(state);
    cost = get<2>(state);

    cost_map[w][h] = cost;

    // 普通に移動
    if (w + 1 < W && cost_map[w + 1][h] > cost && S[w + 1][h] == '.')
      uncalced.push_back(make_tuple(
          w + 1, h, cost)); // マス目に移動でき、コストが小さくできる余地がある
    if (w > 0 && cost_map[w - 1][h] > cost && S[w - 1][h] == '.')
      uncalced.push_back(make_tuple(w - 1, h, cost));
    if (h + 1 < H && cost_map[w][h + 1] > cost && S[w][h + 1] == '.')
      uncalced.push_back(make_tuple(w, h + 1, cost));
    if (h < H && cost_map[w][h - 1] > cost && S[w][h - 1] == '.')
      uncalced.push_back(make_tuple(w, h - 1, cost));

    // ワープ移動
    REP(i, 5) {
      REP(j, 5) {
        int movew = i - 2;
        int moveh = j - 2;
        if (w + movew < W && w + movew >= 0 && h + moveh < H &&
            h + moveh >= 0 && cost_map[w + movew][h + moveh] > cost + 1 &&
            S[w + movew][h + moveh] == '.')
          uncalced.push_back(make_tuple(w + movew, h + moveh, cost + 1));
      }
    }
  }
}

void dfs_warp(ll w, ll h, ll cost) {
  cost_map[w][h] = cost;

  // ワープ移動
  REP(i, 5) {
    REP(j, 5) {
      int movew = i - 2;
      int moveh = j - 2;
      if (w + movew < W && w + movew >= 0 && h + moveh < H && h + moveh >= 0 &&
          cost_map[w + movew][h + moveh] > cost + 1 &&
          S[w + movew][h + moveh] == '.')
        dfs(w + movew, h + moveh, cost + 1);
    }
  }
}

int main() {

  cin >> H >> W >> ch >> cw >> dh >> dw;
  ch--;
  cw--;
  dh--;
  dw--;
  REP(j, H) {
    REP(i, W) {
      cin >> S[i][j];
      cost_map[i][j] = LINF;
    }
  }

  dfs(cw, ch, 0);

  if (cost_map[dw][dh] == LINF) {
    cout << -1 << endl;
  } else {
    cout << cost_map[dw][dh];
  }

  return 0;
}