Problem p01539 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define FOR(i, k, n) for (int i = (k); i < (int)(n); ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) begin(x), end(x)

using namespace std;

struct S {
  int x, y, t;
};
bool operator==(S l, S r) { return l.x == r.x && l.y == r.y && l.t == r.t; }
int to_i(const S &s) { return s.x + 100 + (s.y + 100) * 201 + s.t * 40401; }
namespace std {
template <> struct hash<S> {
  size_t operator()(const S &s) const {
    hash<int> h;
    return h(s.x + h(s.y + h(s.t)));
  }
};
} // namespace std
constexpr int INF = 1000000001;
class Weight {
public:
  Weight() : w(INF) {}
  Weight(int w) : w(w) {}
  operator int() const { return w; }
  operator int() { return w; }

private:
  int w;
};
using Array = unordered_map<S, Weight>;
struct Edge {
  S dest;
  Weight weight;
};
using Edges = vector<Edge>;
using Graph = vector<Edges>;

void add_edge(Graph &g, S src, S dest, Weight weight) {
  g[to_i(src)].push_back((Edge){dest, weight});
}

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

void bfs01(Graph &g, Array &d, S s) {
  d[s] = 0;
  using P = pair<Weight, S>;
  deque<P> que;
  que.push_back(P(0, s));
  while (!que.empty()) {
    P top = que.front();
    que.pop_front();
    Weight dist = top.first;
    S v = top.second;
    if (d[v] < dist)
      continue;
    REP(i, g[to_i(v)].size()) {
      Edge e = g[to_i(v)][i];
      if (d[e.dest] > d[v] + e.weight) {
        d[e.dest] = d[v] + e.weight;
        if (e.weight)
          que.push_back(P(d[e.dest], e.dest));
        else
          que.push_front(P(d[e.dest], e.dest));
      }
    }
  }
}

int main() {
  int sx, sy, gx, gy;
  cin >> sx >> sy >> gx >> gy;
  int n;
  cin >> n;
  set<pair<int, int>> sf;
  REP(i, n) {
    int x, y;
    cin >> x >> y;
    sf.emplace(x, y);
  }
  int lx, ly;
  cin >> lx >> ly;
  Graph g;
  FOR(i, -lx, lx + 1) FOR(j, -ly, ly + 1) REP(k, 6) {
    S s = {i, j, k};
    int dir = abs(i * j * k) % 6;
    int ni = i + di[dir];
    int nj = j + dj[abs(i) % 2][dir];
    if (abs(ni) > lx || abs(nj) > ly)
      continue;
    if (sf.count({ni, nj}))
      continue;
    S t = {ni, nj, (k + 1) % 6};
    add_edge(g, s, t, 0);
  }
  FOR(i, -lx, lx + 1) FOR(j, -ly, ly + 1) REP(k, 6) {
    S s = {i, j, k};
    REP(l, 6) {
      int ni = i + di[l];
      int nj = j + dj[abs(i) % 2][l];
      if (abs(ni) > lx || abs(nj) > ly)
        continue;
      if (sf.count({ni, nj}))
        continue;
      S t = {ni, nj, (k + 1) % 6};
      add_edge(g, s, t, 1);
    }
    S t = {i, j, (k + 1) % 6};
    add_edge(g, s, t, 1);
  }
  Array d;
  S s = {sx, sy, 0};
  bfs01(g, d, s);
  Weight res;
  REP(i, 6) {
    S g = {gx, gy, i};
    res = min(res, d[g]);
  }
  if (res == INF) {
    cout << -1 << endl;
  } else {
    cout << res << endl;
  }
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
#define FOR(i, k, n) for (int i = (k); i < (int)(n); ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) begin(x), end(x)

using namespace std;

struct S {
  int x, y, t;
};
bool operator==(S l, S r) { return l.x == r.x && l.y == r.y && l.t == r.t; }
int to_i(const S &s) { return s.x + 100 + (s.y + 100) * 201 + s.t * 40401; }
namespace std {
template <> struct hash<S> {
  size_t operator()(const S &s) const {
    hash<int> h;
    return h(s.x + h(s.y + h(s.t)));
  }
};
} // namespace std
constexpr int INF = 1000000001;
class Weight {
public:
  Weight() : w(INF) {}
  Weight(int w) : w(w) {}
  operator int() const { return w; }
  operator int() { return w; }

private:
  int w;
};
using Array = unordered_map<S, Weight>;
struct Edge {
  S dest;
  Weight weight;
};
using Edges = vector<Edge>;
using Graph = vector<Edges>;

void add_edge(Graph &g, S src, S dest, Weight weight) {
  g[to_i(src)].push_back((Edge){dest, weight});
}

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

void bfs01(Graph &g, Array &d, S s) {
  d[s] = 0;
  using P = pair<Weight, S>;
  deque<P> que;
  que.push_back(P(0, s));
  while (!que.empty()) {
    P top = que.front();
    que.pop_front();
    Weight dist = top.first;
    S v = top.second;
    if (d[v] < dist)
      continue;
    REP(i, g[to_i(v)].size()) {
      Edge e = g[to_i(v)][i];
      if (d[e.dest] > d[v] + e.weight) {
        d[e.dest] = d[v] + e.weight;
        if (e.weight)
          que.push_back(P(d[e.dest], e.dest));
        else
          que.push_front(P(d[e.dest], e.dest));
      }
    }
  }
}

int main() {
  int sx, sy, gx, gy;
  cin >> sx >> sy >> gx >> gy;
  int n;
  cin >> n;
  set<pair<int, int>> sf;
  REP(i, n) {
    int x, y;
    cin >> x >> y;
    sf.emplace(x, y);
  }
  int lx, ly;
  cin >> lx >> ly;
  Graph g(250000);
  FOR(i, -lx, lx + 1) FOR(j, -ly, ly + 1) REP(k, 6) {
    S s = {i, j, k};
    int dir = abs(i * j * k) % 6;
    int ni = i + di[dir];
    int nj = j + dj[abs(i) % 2][dir];
    if (abs(ni) > lx || abs(nj) > ly)
      continue;
    if (sf.count({ni, nj}))
      continue;
    S t = {ni, nj, (k + 1) % 6};
    add_edge(g, s, t, 0);
  }
  FOR(i, -lx, lx + 1) FOR(j, -ly, ly + 1) REP(k, 6) {
    S s = {i, j, k};
    REP(l, 6) {
      int ni = i + di[l];
      int nj = j + dj[abs(i) % 2][l];
      if (abs(ni) > lx || abs(nj) > ly)
        continue;
      if (sf.count({ni, nj}))
        continue;
      S t = {ni, nj, (k + 1) % 6};
      add_edge(g, s, t, 1);
    }
    S t = {i, j, (k + 1) % 6};
    add_edge(g, s, t, 1);
  }
  Array d;
  S s = {sx, sy, 0};
  bfs01(g, d, s);
  Weight res;
  REP(i, 6) {
    S g = {gx, gy, i};
    res = min(res, d[g]);
  }
  if (res == INF) {
    cout << -1 << endl;
  } else {
    cout << res << endl;
  }
  return 0;
}