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

#include <algorithm>
#include <iostream>
#include <queue>
#include <tuple>
#include <vector>

using namespace std;

struct edge {
  static constexpr auto INF = std::numeric_limits<long long>::max();

  edge(int src, int dst, long long weight)
      : src(src), dst(dst), weight(weight) {}

  bool operator<(const edge &other) const {
    return std::tie(other.weight, src, dst) <
           std::tie(weight, other.src, other.dst);
  }

  int src;
  int dst;
  long long weight;
};

using graph = std::vector<std::vector<edge>>;

void add_edge(graph &g, int src, int dst, long long weight) {
  g[src].emplace_back(src, dst, weight);
}

void dijkstra_shortest_paths(const graph &g, int s, std::vector<long long> &d,
                             std::vector<int> &p) {
  int n = g.size();
  d.assign(n, edge::INF);
  d[s] = 0;
  p.assign(n, -1);
  std::priority_queue<edge> q;
  q.emplace(-2, s, 0);
  while (!q.empty()) {
    auto e = q.top();
    q.pop();
    if (p[e.dst] != -1) {
      continue;
    }
    p[e.dst] = e.src;
    for (auto &f : g[e.dst]) {
      auto w = e.weight + f.weight;
      if (d[f.dst] > w) {
        d[f.dst] = w;
        q.emplace(f.src, f.dst, w);
      }
    }
  }
}

void dijkstra_shortest_paths(const graph &g, int s, std::vector<long long> &d) {
  std::vector<int> p;
  dijkstra_shortest_paths(g, s, d, p);
}

int main() {
  int H, W;
  int Ch, Cw;
  int Dh, Dw;
  vector<string> S;
  vector<vector<int>> best;

  cin >> H >> W >> Ch >> Cw >> Dh >> Dw;
  --Ch;
  --Cw;
  --Dh;
  --Dw;
  S.resize(H);
  for (auto &x : S) {
    cin >> x;
  }

  auto ok = [&](int y, int x) {
    return 0 <= y && y < H && 0 <= x && x < W && S[y][x] == '.';
  };

  auto idx = [&](int y, int x) { return y * W + x; };

  graph g(H * W);
  for (int y = 0; y < H; ++y) {
    for (int x = 0; x < W; ++x) {
      for (int dy = -1; dy <= +1; ++dy) {
        for (int dx = -1; dx <= +1; ++dx) {
          if (abs(dy) + abs(dx) != 1) {
            continue;
          }
          int y2 = y + dy;
          int x2 = x + dx;
          if (!ok(y2, x2)) {
            continue;
          }
          add_edge(g, idx(y, x), idx(y2, x2), 0);
        }
      }

      for (int dy = -2; dy <= +2; ++dy) {
        for (int dx = -2; dx <= +2; ++dx) {
          if (abs(dy) + abs(dx) <= 1) {
            continue;
          }
          int y2 = y + dy;
          int x2 = x + dx;
          if (!ok(y2, x2)) {
            continue;
          }
          add_edge(g, idx(y, x), idx(y2, x2), 1);
        }
      }
    }
  }

  long int goal = idx(Dh, Dw);
  vector<long long> d(H * W);
  dijkstra_shortest_paths(g, idx(Ch, Cw), d);

  if (d[goal] != edge::INF) {
    cout << d[goal] << endl;
  } else {
    cout << -1 << endl;
  }
}


Error: TLE

Fixed submission:

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

using namespace std;

const int INF = 1 << 30;

int main() {
  int H, W;
  int Ch, Cw;
  int Dh, Dw;
  cin >> H >> W >> Ch >> Cw >> Dh >> Dw;
  --Ch;
  --Cw;
  --Dh;
  --Dw;
  vector<string> S(H);
  for (auto &x : S) {
    cin >> x;
  }

  auto ok = [&](int y, int x) {
    return 0 <= y && y < H && 0 <= x && x < W && S[y][x] == '.';
  };

  vector<vector<int>> best(H, vector<int>(W, INF));

  queue<int> q;
  best[Ch][Cw] = 0;
  q.push(Ch);
  q.push(Cw);

  while (!q.empty()) {
    int y = q.front();
    q.pop();
    int x = q.front();
    q.pop();

    if (y == Dh && x == Dw) {
      continue;
    }

    for (int dy = -1; dy <= +1; ++dy) {
      for (int dx = -1; dx <= +1; ++dx) {
        if (abs(dy) + abs(dx) != 1) {
          continue;
        }
        int y2 = y + dy;
        int x2 = x + dx;
        if (!ok(y2, x2)) {
          continue;
        }
        int cost = best[y][x];
        if (cost < best[y2][x2]) {
          best[y2][x2] = cost;
          q.push(y2);
          q.push(x2);
        }
      }
    }

    for (int dy = -2; dy <= +2; ++dy) {
      for (int dx = -2; dx <= +2; ++dx) {
        if (abs(dy) + abs(dx) <= 1) {
          continue;
        }
        int y2 = y + dy;
        int x2 = x + dx;
        if (!ok(y2, x2)) {
          continue;
        }
        int cost = best[y][x] + 1;
        if (cost < best[y2][x2]) {
          best[y2][x2] = cost;
          q.push(y2);
          q.push(x2);
        }
      }
    }
  }

  if (best[Dh][Dw] < INF) {
    cout << best[Dh][Dw] << endl;
  } else {
    cout << -1 << endl;
  }
}