Problem p02579 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>
#define MOD 1000000007
#define INF 1001001001
#define LINF 1001001001001001001
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define bit(n) (1LL << (n))
using namespace std;

typedef long long ll;
typedef pair<int, int> P;
typedef pair<ll, ll> LLP;

int H, W;

int getPos(int i, int j) { return i * H + j; }

bool check(int i, int j) { return i >= 0 && i < H && j >= 0 && j < W; }

int main() {

  cin >> H >> W;
  P C, D;
  cin >> C.first >> C.second >> D.first >> D.second;
  C.first--;
  C.second--;
  D.first--;
  D.second--;
  vector<string> S(H);
  rep(i, H) cin >> S[i];

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

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

  queue<P> next_que, que;
  next_que.emplace(C.first, C.second);
  int now = 0;

  while (!next_que.empty()) {
    while (!next_que.empty()) {
      que.push(next_que.front());
      next_que.pop();
    }
    while (!que.empty()) {
      P p = que.front();
      que.pop();
      if (maze[p.first][p.second] <= now)
        continue;
      maze[p.first][p.second] = now;
      rep(i, 4) {
        if (check(p.first + dy[i], p.second + dx[i]) &&
            S[p.first + dy[i]][p.second + dx[i]] == '.' &&
            maze[p.first + dy[i]][p.second + dx[i]] > now) {
          que.emplace(p.first + dy[i], p.second + dx[i]);
        }
      }
      for (int i = -2; i <= 2; i++)
        for (int j = -2; j <= 2; j++) {
          if (check(p.first + i, p.second + j) &&
              S[p.first + i][p.second + j] == '.' &&
              maze[p.first + i][p.second + j] == INF) {
            next_que.emplace(p.first + i, p.second + j);
          }
        }
    }
    now++;
  }

  if (maze[D.first][D.second] == INF)
    cout << -1 << endl;
  else
    cout << maze[D.first][D.second] << endl;

  return 0;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
#define MOD 1000000007
#define INF 1001001001
#define LINF 1001001001001001001
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define bit(n) (1LL << (n))
using namespace std;

typedef long long ll;
typedef pair<int, int> P;
typedef pair<ll, ll> LLP;

/*
    Dijkstra's Algorithm (Single Source Shortest Path)
        - for directed graph
        - NO edges have negative cost
        - 0-indexed vertexes
 */

class Dijkstra {
private:
  vector<vector<LLP>> G;
  vector<ll> cost;
  vector<ll> par;
  priority_queue<LLP, vector<LLP>, greater<LLP>> que;

public:
  Dijkstra(ll n, vector<vector<ll>> g, ll s);
  ll getCost(ll target);
  vector<vector<ll>> getPath(ll target);
};

// n: |V|
// g: [point_from, point_to, cost] (directed graph)
// s: start point
Dijkstra::Dijkstra(ll n, vector<vector<ll>> g, ll s) {
  for (ll i = 0; i < n; i++) {
    G.push_back(vector<LLP>());
    cost.push_back(-1);
    par.push_back(-1);
  }

  // create adj-Graph
  for (ll i = 0; i < g.size(); i++) {
    G[g[i][0]].push_back(make_pair(g[i][1], g[i][2]));
  }

  // initialize
  cost[s] = 0;
  par[s] = s;
  que.push(make_pair(cost[s], s));

  while (!que.empty()) {
    LLP p = que.top();
    que.pop();

    if (cost[p.second] < p.first)
      continue;
    for (int i = 0; i < G[p.second].size(); i++) {
      if (cost[G[p.second][i].first] < 0 ||
          cost[G[p.second][i].first] > cost[p.second] + G[p.second][i].second) {
        cost[G[p.second][i].first] = cost[p.second] + G[p.second][i].second;
        par[G[p.second][i].first] = p.second;
        que.push(make_pair(cost[G[p.second][i].first], G[p.second][i].first));
      }
    }
  }
}

// returns the minimum cost from the start point to the target.
// (if there is no path to the target, this returns -1.)
// (if the target is the start point, this returns 0.)
ll Dijkstra::getCost(ll target) { return cost[target]; }

// returns a list of path: Array of [point_from, point_to, cost].
// (if there is no path to the target or the target is the start point, this
// returns an empty vector.)
vector<vector<ll>> Dijkstra::getPath(ll target) {

  vector<vector<ll>> reversePath = vector<vector<ll>>(0);

  if (cost[target] <= 0)
    return reversePath;

  ll now_p = target;
  while (par[now_p] != now_p) {
    vector<ll> temp(3);
    temp[0] = par[now_p];
    temp[1] = now_p;
    temp[2] = cost[now_p] - cost[par[now_p]];
    reversePath.push_back(temp);
    now_p = par[now_p];
  }

  vector<vector<ll>> path = vector<vector<ll>>(0);
  for (ll i = reversePath.size() - 1; i >= 0; i--)
    path.push_back(reversePath[i]);

  return path;
}

int H, W;

int getPos(int i, int j) { return i * H + j; }

bool check(int i, int j) { return i >= 0 && i < H && j >= 0 && j < W; }

int main() {

  cin >> H >> W;
  P C, D;
  cin >> C.first >> C.second >> D.first >> D.second;
  vector<string> S(H);
  rep(i, H) cin >> S[i];

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

  vector<vector<ll>> edges;

  rep(i, H) rep(j, W) {
    if (S[i][j] == '#')
      continue;
    rep(k, 4) {
      if (check(i + dy[k], j + dx[k]) && S[i + dy[k]][j + dx[k]] == '.') {
        vector<ll> e(3);
        e[0] = getPos(i, j);
        e[1] = getPos(i + dy[k], j + dx[k]);
        e[2] = 0;
        edges.push_back(e);
        swap(e[0], e[1]);
        edges.push_back(e);
      }
    }
    for (int k = -2; k <= 2; k++)
      for (int l = -2; l <= 2; l++) {
        if (check(i + k, j + l) && S[i + k][j + l] == '.') {
          vector<ll> e(3);
          e[0] = getPos(i, j);
          e[1] = getPos(i + k, j + l);
          e[2] = 1;
          edges.push_back(e);
          swap(e[0], e[1]);
          edges.push_back(e);
        }
      }
  }

  Dijkstra tree(H * W, edges, getPos(C.first - 1, C.second - 1));

  cout << tree.getCost(getPos(D.first - 1, D.second - 1)) << endl;

  return 0;
}