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

#include <bits/stdc++.h>
using namespace std;
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
using ll = long long;
using P = pair<ll, ll>;
const long double PI = acos(-1.0L);
ll GCD(ll a, ll b) { return b ? GCD(b, a % b) : a; }
ll LCM(ll a, ll b) { return a / GCD(a, b) * b; }

int dx[] = {-1, 0, 1, 0};
int dy[] = {0, -1, 0, 1};

int h, w;
struct pqdata {
  int x, y;
  ll cnt;
  bool operator<(const pqdata &r) const { return cnt > r.cnt; }
};

int main() {
  cin >> h >> w;
  pqdata first;
  cin >> first.y >> first.x;
  first.x--;
  first.y--;
  first.cnt = 0;
  int dh, dw;
  cin >> dh >> dw;
  dh--;
  dw--;
  vector<vector<char>> smap(h, vector<char>(w, '.'));
  for (int i = 0; i < h; ++i) {
    for (int j = 0; j < w; ++j) {
      cin >> smap[i][j];
    }
  }
  vector<vector<int>> scnt(h, vector<int>(w, 1e9));
  scnt[first.y][first.x] = 0;
  priority_queue<pqdata> pque;
  pque.push(first);

  while (!pque.empty()) {
    pqdata now = pque.top();
    pque.pop();
    if (now.x == dw && now.y == dh)
      break;
    int nx, ny, ncnt;
    // ワープしない
    for (int i = 0; i < 4; ++i) {
      nx = now.x + dx[i], ny = now.y + dy[i];
      ncnt = now.cnt;
      if (nx >= 0 && nx < w && ny >= 0 && ny < h) {
        if (smap[ny][nx] != '#') {
          if (scnt[ny][nx] > ncnt) {
            scnt[ny][nx] = ncnt;
            pqdata next;
            next.x = nx;
            next.y = ny;
            next.cnt = ncnt;
            pque.push(next);
          }
        }
      }
    }

    // ワープあり
    for (int i = -2; i <= 2; ++i) {
      for (int j = -2; j <= 2; ++j) {
        if (i == 0 && j == 0)
          continue;
        nx = now.x + j, ny = now.y + i;
        ncnt = now.cnt + 1;
        if (nx >= 0 && nx < w && ny >= 0 && ny < h) {
          if (smap[ny][nx] != '#') {
            if (scnt[ny][nx] > ncnt) {
              scnt[ny][nx] = ncnt;
              pqdata next;
              next.x = nx;
              next.y = ny;
              next.cnt = ncnt;
              pque.push(next);
            }
          }
        }
      }
    }
  }

  int ans = scnt[dh][dw];
  if (ans == 1e9)
    cout << -1 << endl;
  else
    cout << ans << endl;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
using ll = long long;
using P = pair<ll, ll>;
const long double PI = acos(-1.0L);
ll GCD(ll a, ll b) { return b ? GCD(b, a % b) : a; }
ll LCM(ll a, ll b) { return a / GCD(a, b) * b; }

int dx[] = {-1, 0, 1, 0};
int dy[] = {0, -1, 0, 1};

int h, w;
struct Data {
  int x, y, cnt;
};

int main() {
  cin >> h >> w;
  int ch, cw, dh, dw;
  cin >> ch >> cw;
  cin >> dh >> dw;
  ch--;
  cw--;
  dh--;
  dw--;
  vector<vector<char>> smap(h, vector<char>(w, '.'));
  for (int i = 0; i < h; ++i) {
    for (int j = 0; j < w; ++j) {
      cin >> smap[i][j];
    }
  }
  Data first;
  first.x = cw;
  first.y = ch;
  first.cnt = 0;

  queue<Data> que;
  que.push(first);
  vector<vector<int>> scnt(h, vector<int>(w, 1e9));
  scnt[ch][cw] = 0;
  while (!que.empty()) {
    Data now = que.front();
    que.pop();
    // cout << "x y " << now.x << " " << now.y << endl;
    // ワープしない
    for (int i = 0; i < 4; ++i) {
      int nx = now.x + dx[i], ny = now.y + dy[i];
      int ncnt = now.cnt;
      if (nx >= 0 && nx < w && ny >= 0 && ny < h) {
        if (smap[ny][nx] != '#' && scnt[ny][nx] > ncnt) {
          // 地道な移動でワープが少ないやつ
          scnt[ny][nx] = ncnt;
          Data next;
          next.x = nx;
          next.y = ny;
          next.cnt = ncnt;
          que.push(next);
        }
      }
    }
    // ワープする
    for (int i = -2; i <= 2; ++i) {
      for (int j = -2; j <= 2; ++j) {
        int nx = now.x + j, ny = now.y + i;
        int ncnt = now.cnt + 1;
        if (nx >= 0 && nx < w && ny >= 0 && ny < h) {
          if (smap[ny][nx] != '#' && scnt[ny][nx] > ncnt) {
            scnt[ny][nx] = ncnt;
            Data next;
            next.x = nx;
            next.y = ny;
            next.cnt = ncnt;
            que.push(next);
          }
        }
      }
    }
  }

  int ans = scnt[dh][dw];
  if (ans == 1e9)
    cout << -1 << endl;
  else
    cout << ans << endl;
}