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

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define P pair<ll, ll>

const ll INF = LLONG_MAX;

struct Edge { // グラフ
  ll to, cap, rev;
  Edge(ll _to, ll _cap, ll _rev) {
    to = _to;
    cap = _cap;
    rev = _rev;
  }
};
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
void add_edge(Graph &G, ll from, ll to, ll cap, bool revFlag, ll revCap) {
  G[from].push_back(Edge(to, cap, (ll)G[to].size()));
  if (revFlag)
    G[to].push_back(Edge(
        from, revCap, (ll)G[from].size() - 1)); // 最小カット計算時逆辺は0にする
}

void Dijkstra(Graph &G, ll s, vector<ll> &d) { // O(|E|log|V|)
  d.resize(G.size());
  rep(i, d.size()) d[i] = INF;
  d[s] = 0;
  priority_queue<P, vector<P>, greater<P>> q;
  q.push(make_pair(0, s));
  while (!q.empty()) {
    P a = q.top();
    q.pop();
    if (d[a.second] < a.first)
      continue;
    rep(i, G[a.second].size()) {
      Edge e = G[a.second][i];
      if (d[e.to] > d[a.second] + e.cap) {
        d[e.to] = d[a.second] + e.cap;
        q.push(make_pair(d[e.to], e.to));
      }
    }
  }
}

char grid[1010][1010];
int group[1010][1010];
int h, w, ch, cw, dh, dw;

void dfs(int i, int j, int &gr) {
  if (i < 0 || i >= h || j < 0 || j >= w)
    return;
  if (grid[i][j] == '#')
    return;
  if (group[i][j] != -1)
    return;
  group[i][j] = gr;
  dfs(i + 1, j, gr);
  dfs(i - 1, j, gr);
  dfs(i, j + 1, gr);
  dfs(i, j - 1, gr);
}

int di[] = {-2, -2, -2, -2, -2, -1, -1, -1, -1, 0,
            0,  1,  1,  1,  1,  2,  2,  2,  2,  2};
int dj[] = {-2, -1, 0,  1, 2, -2, -1, 1, 2, -2,
            2,  -2, -1, 1, 2, -2, -1, 0, 1, 2};

int main() {
  cin >> h >> w >> ch >> cw >> dh >> dw;
  ch--;
  cw--;
  dh--;
  dw--;
  rep(i, h) rep(j, w) {
    cin >> grid[i][j];
    group[i][j] = -1;
  }
  int tmp = 0;
  rep(i, h) rep(j, w) {
    if (grid[i][j] != '#' && group[i][j] == -1) {
      dfs(i, j, tmp);
      tmp++;
    }
  }
  Graph g(tmp);
  set<P> st;
  rep(pi, h) rep(pj, w) {
    if (grid[pi][pj] == '#')
      continue;
    rep(i, 20) {
      int ni = pi + di[i], nj = pj + dj[i];
      if (ni < 0 || ni >= h || nj < 0 || nj >= w)
        continue;
      if (grid[ni][nj] == '#')
        continue;
      int fir = group[pi][pj], sec = group[ni][nj];
      if (fir == sec)
        continue;
      st.insert(make_pair(min(fir, sec), max(fir, sec)));
    }
  }
  for (auto x : st) {
    int a, b;
    tie(a, b) = x;
    add_edge(g, a, b, 1, true, 1);
  }
  vector<ll> d;
  int s = group[ch][cw];
  Dijkstra(g, s, d);
  if (d[group[dh][dw]] == INF)
    cout << -1 << endl;
  else
    cout << d[group[dh][dw]] << endl;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define P pair<int, int>

char grid[1010][1010];
int cost[1010][1010];
int di[] = {0, 1, 0, -1, -2, -2, -2, -2, -2, -1, -1, -1, -1, -1,
            0, 0, 0, 0,  1,  1,  1,  1,  1,  2,  2,  2,  2,  2};
int dj[] = {1,  0,  -1, 0, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2,
            -2, -1, 1,  2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2};
const int INF = INT_MAX;

int main() {
  int h, w, ch, cw, dh, dw;
  cin >> h >> w >> ch >> cw >> dh >> dw;
  ch--;
  cw--;
  dh--;
  dw--;
  rep(i, h) rep(j, w) {
    cin >> grid[i][j];
    cost[i][j] = INF;
  }
  queue<P> q;
  q.push(make_pair(ch, cw));
  cost[ch][cw] = 0;
  while (!q.empty()) {
    int pi, pj;
    tie(pi, pj) = q.front();
    q.pop();
    int past = cost[pi][pj];
    rep(i, 28) {
      int ni = pi + di[i], nj = pj + dj[i];
      if (ni < 0 || ni >= h || nj < 0 || nj >= w)
        continue;
      if (grid[ni][nj] == '#')
        continue;
      if (cost[ni][nj] <= past)
        continue;
      if (i < 4)
        cost[ni][nj] = past;
      else
        cost[ni][nj] = past + 1;
      q.push(make_pair(ni, nj));
    }
  }
  if (cost[dh][dw] == INF)
    cout << -1 << endl;
  else
    cout << cost[dh][dw] << endl;
}