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

#include <deque>
#include <iostream>
#include <limits>
#include <string>
#include <utility>
#include <vector>

class CDelta {
public:
  CDelta() = delete;
  CDelta(int dx, int dy, int dCost) : m_dX(dx), m_dY(dy), m_dCost(dCost){};

  int GetDx() const { return m_dX; }
  int GetDy() const { return m_dY; }
  int GetDCost() const { return m_dCost; }

private:
  int m_dX;
  int m_dY;
  int m_dCost;
};

int main() {
  int h, w;
  std::cin >> h >> w;
  int gx, gy;
  std::cin >> gy >> gx;
  --gx;
  --gy;

  int x, y;
  std::cin >> y >> x;
  --x;
  --y;

  std::vector<std::vector<bool>> isRoad(h, std::vector<bool>(w, false));

  for (auto &r : isRoad) {
    std::string row;
    std::cin >> row;
    for (size_t index = 0; index < r.size(); ++index) {
      r[index] = (row[index] == '.');
    }
  }

  constexpr auto UNREACHABLE = std::numeric_limits<int>::max();
  std::vector<std::vector<int>> warpCount(h, std::vector<int>(w, UNREACHABLE));
  // bfsで検索
  std::deque<std::pair<int, int>> q;
  q.push_back(std::make_pair(x, y));
  warpCount[y][x] = 0;
  while (!q.empty()) {
    auto pos = q.front();
    const auto cx = pos.first;
    const auto cy = pos.second;
    q.pop_front();

    // 移動チェック
    auto checkAndPush = [&](int x, int y, int penalty) {
      if (x < 0 || w <= x) {
        return;
      }

      if (y < 0 || h <= y) {
        return;
      }

      if (!isRoad[y][x]) {
        return;
      }

      const auto cost = warpCount[cy][cx] + penalty;
      if (warpCount[y][x] > cost) {
        warpCount[y][x] = cost;
        if (penalty > 0) {
          q.push_back(std::make_pair(x, y));
        } else {
          q.push_front(std::make_pair(x, y));
        }
      }
    };

    static const std::vector<CDelta> wd = {
        // 徒歩
        CDelta(0, -1, 0), CDelta(-1, 0, 0), CDelta(1, 0, 0), CDelta(0, 1, 0),
        // ワープ
        CDelta(-2, -2, 1), CDelta(-1, -2, 1), CDelta(0, -2, 1),
        CDelta(1, -2, 1), CDelta(2, -2, 1), CDelta(-2, -1, 1),
        CDelta(-1, -1, 1), CDelta(1, -1, 1), CDelta(2, -1, 1), CDelta(-2, 0, 1),
        CDelta(2, 0, 1), CDelta(-2, 1, 1), CDelta(-1, 1, 1), CDelta(1, 1, 1),
        CDelta(2, 1, 1), CDelta(-2, 2, 1), CDelta(-1, 2, 1), CDelta(0, 2, 1),
        CDelta(1, 2, 1), CDelta(2, 2, 1)};

    for (const auto &dt : wd) {
      checkAndPush(cx + dt.GetDx(), cy + dt.GetDy(), dt.GetDCost());
    }
  }

  if (warpCount[gy][gx] == UNREACHABLE) {
    std::cout << -1;
  } else {
    std::cout << warpCount[gy][gx];
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <iostream>
#include <limits>
#include <queue>
#include <string>
#include <utility>
#include <vector>

class CDelta {
public:
  CDelta() = delete;
  CDelta(int dx, int dy, int dCost) : m_dX(dx), m_dY(dy), m_dCost(dCost){};

  int GetDx() const { return m_dX; }
  int GetDy() const { return m_dY; }
  int GetDCost() const { return m_dCost; }

private:
  int m_dX;
  int m_dY;
  int m_dCost;
};

int main() {
  int h, w;
  std::cin >> h >> w;
  int gx, gy;
  std::cin >> gy >> gx;
  --gx;
  --gy;

  int x, y;
  std::cin >> y >> x;
  --x;
  --y;

  std::vector<std::vector<bool>> isRoad(h, std::vector<bool>(w, false));

  for (auto &r : isRoad) {
    std::string row;
    std::cin >> row;
    for (size_t index = 0; index < r.size(); ++index) {
      r[index] = (row[index] == '.');
    }
  }

  constexpr auto UNREACHABLE = std::numeric_limits<int>::max();
  std::vector<std::vector<int>> warpCount(h, std::vector<int>(w, UNREACHABLE));
  // bfsで検索
  std::queue<std::pair<int, int>> q;
  q.push(std::make_pair(x, y));
  warpCount[y][x] = 0;
  while (!q.empty()) {
    auto pos = q.front();
    const auto cx = pos.first;
    const auto cy = pos.second;
    q.pop();

    // 移動チェック
    auto checkAndPush = [&](int x, int y, int penalty) {
      if (x < 0 || w <= x) {
        return;
      }

      if (y < 0 || h <= y) {
        return;
      }

      if (!isRoad[y][x]) {
        return;
      }

      const auto cost = warpCount[cy][cx] + penalty;
      if (warpCount[y][x] > cost) {
        warpCount[y][x] = cost;
        q.push(std::make_pair(x, y));
      }
    };
    static const std::vector<CDelta> wd = {
        // 徒歩
        CDelta(0, -1, 0), CDelta(-1, 0, 0), CDelta(1, 0, 0), CDelta(0, 1, 0),
        // ワープ
        CDelta(-2, -2, 1), CDelta(-1, -2, 1), CDelta(0, -2, 1),
        CDelta(1, -2, 1), CDelta(2, -2, 1), CDelta(-2, -1, 1),
        CDelta(-1, -1, 1), CDelta(1, -1, 1), CDelta(2, -1, 1), CDelta(-2, 0, 1),
        CDelta(2, 0, 1), CDelta(-2, 1, 1), CDelta(-1, 1, 1), CDelta(1, 1, 1),
        CDelta(2, 1, 1), CDelta(-2, 2, 1), CDelta(-1, 2, 1), CDelta(0, 2, 1),
        CDelta(1, 2, 1), CDelta(2, 2, 1)};

    for (const auto &dt : wd) {
      checkAndPush(cx + dt.GetDx(), cy + dt.GetDy(), dt.GetDCost());
    }
  }

  if (warpCount[gy][gx] == UNREACHABLE) {
    std::cout << -1;
  } else {
    std::cout << warpCount[gy][gx];
  }

  return 0;
}