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

// ダイクストラ法
#include "bits/stdc++.h"
#include <queue>
using namespace std;
#define REP(i, n) for (ll i = 0; i < n; i++)
#define ll long long
#define MOD 1000000007LL
#define llMAX 9223372036854775807LL
#define llMIN -9223372036854775808LL
using vi = vector<ll>;  // intの1次元の型に vi という別名をつける
using vvi = vector<vi>; // intの2次元の型に vvi という別名をつける

ll n, k;
const int N = 3e6;
vector<vector<pair<int, double>>> g;

using pairdi = pair<double, int>;
vector<double>
    leng(N, 4503599627370496.0); // ある点を始点として、全体nodeへの最短距離
// 小さいほうが先頭にくるよう。ダイクストラ法などで使用を想定
// doubleは長さ、intはnodeidを意味している
auto compare = [](pairdi a, pairdi b) { return a.first > b.first; };
priority_queue<pairdi, vector<pairdi>, decltype(compare)> que{compare};

// 今見ている頂点から伸びる頂点をqueに溜める
void pushg(int nodeid) {
  double len = leng[nodeid];
  for (auto to : g[nodeid]) {
    if (to.second == 100.0) {
      double dtmp = fmod(len, double(k));
      to.second = (double)k - dtmp;
    }
    que.emplace(len + to.second, to.first); // 長さ,nodeid
  }
}

void djk(int first_node, int second_node) {
  // 初期値をプライオリティーキューにいれる
  que.emplace(0.0, first_node);
  que.emplace(0.0, second_node);
  // キューがなくなるまでやる
  int nodeid;
  double ddlen;
  while (!que.empty()) {
    nodeid = que.top().second;
    ddlen = que.top().first;
    if (leng[nodeid] > ddlen) {
      leng[nodeid] = ddlen;
      pushg(nodeid);
    }
    que.pop();
  }
  return;
}

int main() {
  ll h, w;
  cin >> h >> w >> k;
  n = h * w;
  ll x1, y1, x2, y2;
  cin >> y1 >> x1 >> y2 >> x2;
  x1--;
  y1--;
  x2--;
  y2--;
  vvi data(w, vi(h)); // N * M の2次元配列

  g.resize(n * 2 + 1);

  for (ll i = 0; i < h; i++) {
    string s;
    cin >> s;
    for (ll j = 0; j < w; j++) {
      data[j][i] = (s[j] == '.');
    }
  }

  for (ll i = 0; i < w; i++) {
    for (ll j = 0; j < h; j++) {
      ll a = j * w + i;
      ll an = j * w + i + n;
      ll b = j * w + i;
      ll bn = j * w + i + n;
      if (i != 0) {
        if (data[i - 1][j]) {
          g[a].emplace_back(a - 1, 1.0);
          g[a].emplace_back(a + n - 1, 100.0);
        }
      }

      if (i != w - 1) {
        if (data[i + 1][j]) {
          g[a].emplace_back(a + 1, 1.0);
          g[a].emplace_back(a + n + 1, 100.0);
        }
      }

      if (j != 0) {
        if (data[i][j - 1]) {
          g[a + n].emplace_back(a - w, 100.0);
          g[a + n].emplace_back(a + n - w, 1.0);
        }
      }

      if (j != h - 1) {
        if (data[i][j + 1]) {
          g[a + n].emplace_back(a + w, 100.0);
          g[a + n].emplace_back(a + n + w, 1.0);
        }
      }
    }
  }

  djk(x1 + y1 * w, x1 + y1 * w + n);

  ll ans = min((ll)(leng[x2 + y2 * w]), (ll)(leng[x2 + y2 * w + n]));
  if (ans == 4503599627370496LL) {
    ans = -1;
  } else {
    ans = (ans - 1) / k + 1;
  }

  cout << ans << endl;
  return 0;
}

Error: 0

Fixed submission:

// ダイクストラ法
#include "bits/stdc++.h"
#include <queue>
using namespace std;
#define REP(i, n) for (ll i = 0; i < n; i++)
#define ll long long
#define MOD 1000000007LL
#define llMAX 9223372036854775807LL
#define llMIN -9223372036854775808LL
using vi = vector<ll>;  // intの1次元の型に vi という別名をつける
using vvi = vector<vi>; // intの2次元の型に vvi という別名をつける

ll n, k;
const int N = 1e5;
vector<vector<pair<int, double>>> g;

using pairdi = pair<double, int>;
vector<double>
    leng(N, 4503599627370496.0); // ある点を始点として、全体nodeへの最短距離
// 小さいほうが先頭にくるよう。ダイクストラ法などで使用を想定
// doubleは長さ、intはnodeidを意味している
auto compare = [](pairdi a, pairdi b) { return a.first > b.first; };
priority_queue<pairdi, vector<pairdi>, decltype(compare)> que{compare};

// 今見ている頂点から伸びる頂点をqueに溜める
void pushg(int nodeid) {
  double len = leng[nodeid];
  for (auto to : g[nodeid]) {
    if (to.second == 100.0) {
      double dtmp = fmod(len, double(k));
      to.second = (double)k - dtmp;
    }
    que.emplace(len + to.second, to.first); // 長さ,nodeid
  }
}

void djk(int first_node, int second_node) {
  // 初期値をプライオリティーキューにいれる
  que.emplace(0.0, first_node);
  que.emplace(0.0, second_node);
  // キューがなくなるまでやる
  int nodeid;
  double ddlen;
  while (!que.empty()) {
    nodeid = que.top().second;
    ddlen = que.top().first;
    if (leng[nodeid] > ddlen) {
      leng[nodeid] = ddlen;
      pushg(nodeid);
    }
    que.pop();
  }
  return;
}

int main() {
  ll h, w;
  cin >> h >> w >> k;
  n = h * w;
  ll x1, y1, x2, y2;
  cin >> y1 >> x1 >> y2 >> x2;
  x1--;
  y1--;
  x2--;
  y2--;
  vvi data(w, vi(h)); // N * M の2次元配列

  g.resize(n * 2 + 1);

  for (ll i = 0; i < h; i++) {
    string s;
    cin >> s;
    for (ll j = 0; j < w; j++) {
      data[j][i] = (s[j] == '.');
    }
  }

  for (ll i = 0; i < w; i++) {
    for (ll j = 0; j < h; j++) {
      ll a = j * w + i;
      ll an = j * w + i + n;
      ll b = j * w + i;
      ll bn = j * w + i + n;
      if (i != 0) {
        if (data[i - 1][j]) {
          g[a].emplace_back(a - 1, 1.0);
          g[a].emplace_back(a + n - 1, 100.0);
        }
      }

      if (i != w - 1) {
        if (data[i + 1][j]) {
          g[a].emplace_back(a + 1, 1.0);
          g[a].emplace_back(a + n + 1, 100.0);
        }
      }

      if (j != 0) {
        if (data[i][j - 1]) {
          g[a + n].emplace_back(a - w, 100.0);
          g[a + n].emplace_back(a + n - w, 1.0);
        }
      }

      if (j != h - 1) {
        if (data[i][j + 1]) {
          g[a + n].emplace_back(a + w, 100.0);
          g[a + n].emplace_back(a + n + w, 1.0);
        }
      }
    }
  }

  djk(x1 + y1 * w, x1 + y1 * w + n);

  ll ans = min((ll)(leng[x2 + y2 * w]), (ll)(leng[x2 + y2 * w + n]));
  if (ans == 4503599627370496LL) {
    ans = -1;
  } else {
    ans = (ans - 1) / k + 1;
  }

  cout << ans << endl;
  return 0;
}