Problem p02368 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm> // other
#include <bitset>
#include <cassert> // c
#include <complex>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream> // io
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <regex>
#include <set>
#include <sstream>
#include <stack>
#include <vector> // container
using namespace std;

typedef int32_t i32;
typedef int64_t i64;
typedef i64 ll;
typedef uint32_t uint;
typedef uint64_t ull;

#define ALL(c) (begin(c)), (end(c))
#define REP(i, n) FOR(i, 0, n)
#define REPr(i, n) FORr(i, 0, n)
#define FOR(i, l, r) for (int i = (int)(l); i < (int)(r); ++i)
#define FORr(i, l, r) for (int i = (int)(r)-1; i >= (int)(l); --i)
#define EACH(it, o)                                                            \
  for (__typeof((o).begin()) it = (o).begin(); it != (o).end(); ++it)
#define IN(l, v, r) ((l) <= (v) && (v) < (r))

// debug
#define DUMP(x) cerr << #x << " = " << (x)
#define DUMPLN(x) DUMP(x) << endl
#define DEBUG(x) DUMP(x) << LINE() << " " << __FILE__
#define DEBUGLN(x) DEBUG(x) << endl
#define LINE() cerr << " (L" << __LINE__ << ")"
#define LINELN() LINE() << endl
#define CHECK(exp, act)                                                        \
  if (exp != act) {                                                            \
    DUMPLN(exp);                                                               \
    DEBUGLN(act);                                                              \
  }
#define STOP(e)                                                                \
  CHECK(e, true);                                                              \
  if (!(e))                                                                    \
    exit(1);

class range {
private:
  struct Iter {
    int v;
    int operator*() { return v; }
    bool operator!=(Iter &itr) { return v < itr.v; }
    void operator++() { ++v; }
  };
  Iter i, n;

public:
  range(int n) : i({0}), n({n}) {}
  range(int i, int n) : i({i}), n({n}) {}
  Iter &begin() { return i; }
  Iter &end() { return n; }
};

// output
template <typename T> ostream &operator<<(ostream &os, const vector<T> &as) {
  REP(i, as.size()) {
    if (i != 0)
      os << " ";
    os << as[i];
  }
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const vector<vector<T>> &as) {
  REP(i, as.size()) {
    if (i != 0)
      os << endl;
    os << as[i];
  }
  return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &ss) {
  bool isF = true;
  for (auto &v : ss) {
    if (!isF)
      os << " ";
    os << v;
    isF = false;
  }
  return os;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
  os << p.first << " " << p.second;
  return os;
}
template <typename K, typename V>
ostream &operator<<(ostream &os, const map<K, V> &m) {
  bool isF = true;
  for (auto &p : m) {
    if (!isF)
      os << endl;
    os << p;
    isF = false;
  }
  return os;
}
template <typename T1> ostream &operator<<(ostream &os, const tuple<T1> &t) {
  os << get<0>(t);
  return os;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const tuple<T1, T2> &t) {
  os << get<0>(t) << " " << get<1>(t);
  return os;
}
template <typename T1, typename T2, typename T3>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3> &t) {
  os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t);
  return os;
}
template <typename T1, typename T2, typename T3, typename T4>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3, T4> &t) {
  os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " " << get<3>(t);
  return os;
}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3, T4, T5> &t) {
  os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " " << get<3>(t)
     << " " << get<4>(t);
  return os;
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
          typename T6>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3, T4, T5, T6> &t) {
  os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " " << get<3>(t)
     << " " << get<4>(t) << " " << get<5>(t);
  return os;
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
          typename T6, typename T7>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3, T4, T5, T6, T7> &t) {
  os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " " << get<3>(t)
     << " " << get<4>(t) << " " << get<5>(t) << " " << get<6>(t);
  return os;
}

// input
char tmp[1000];
#define nextInt(n) scanf("%d", &n)
#define nextLong(n) scanf("%lld", &n) // I64d
#define nextDouble(n) scanf("%lf", &n)
#define nextChar(n) scanf("%c", &n)
#define nextString(n)                                                          \
  scanf("%s", tmp);                                                            \
  n = tmp

// values
template <class T> T INF() { assert(false); };
template <> int INF<int>() { return 1 << 28; };
template <> ll INF<ll>() { return 1LL << 58; };
template <> double INF<double>() { return 1e16; };

namespace __scc {
typedef vector<vector<int>> Graph;
// O(V+E)
class Scc {
public:
  // private:
  int N;
  Graph g;
  vector<int> ord, low, cmp;
  vector<bool> vis;
  stack<int> st;
  vector<bool> S;
  int gi;
  void dfs(int v, int p, int &k) {
    vis[v] = true;
    ord[v] = k++;
    low[v] = ord[v];
    st.push(v);
    S[v] = true;
    for (int to : g[v]) {
      if (!vis[to]) {
        dfs(to, v, k);
        low[v] = min(low[v], low[to]);
      } else if (S[to]) {
        low[v] = min(low[v], ord[to]);
      }
    }
    if (low[v] != ord[v])
      return;
    while (st.top() != v) {
      cmp[st.top()] = gi;
      S[st.top()] = false;
      st.pop();
    }
    cmp[v] = gi;
    S[v] = false;
    st.pop();
    gi++;
  }

public:
  Scc(int N) : N(N) {
    g = Graph(N);
    ord = cmp = low = vector<int>(N, -1);
    vis = S = vector<bool>(N);
  }
  void add_edge(int f, int t) { g[f].push_back(t); }
  void scc() {
    int k = 0;
    gi = 0;
    REP(v, N) if (!vis[v]) dfs(v, -1, k);
  }
  bool same(int i, int j) { return cmp[i] == cmp[j]; }
};
} // namespace __scc
using namespace __scc;

class Main {
public:
  void run() {
    // include check
    int N, E;
    nextInt(N);
    nextInt(E);
    Scc g(N);
    REP(i, E) {
      int s, t;
      nextInt(s);
      nextInt(t);
      g.add_edge(s, t);
    }
    g.scc();
    cerr << g.cmp << endl;
    int Q;
    nextInt(Q);
    REP(q, Q) {
      int u, v;
      nextInt(u);
      nextInt(v);
      cout << (g.same(u, v) ? 1 : 0) << endl;
    }
  }
};

int main() {
  cout << fixed << setprecision(20);
  cin.tie(0);
  ios::sync_with_stdio(false);
  Main().run();
  return 0;
}

Fixed submission:
#include <algorithm> // other
#include <bitset>
#include <cassert> // c
#include <complex>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream> // io
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <regex>
#include <set>
#include <sstream>
#include <stack>
#include <vector> // container
using namespace std;

typedef int32_t i32;
typedef int64_t i64;
typedef i64 ll;
typedef uint32_t uint;
typedef uint64_t ull;

#define ALL(c) (begin(c)), (end(c))
#define REP(i, n) FOR(i, 0, n)
#define REPr(i, n) FORr(i, 0, n)
#define FOR(i, l, r) for (int i = (int)(l); i < (int)(r); ++i)
#define FORr(i, l, r) for (int i = (int)(r)-1; i >= (int)(l); --i)
#define EACH(it, o)                                                            \
  for (__typeof((o).begin()) it = (o).begin(); it != (o).end(); ++it)
#define IN(l, v, r) ((l) <= (v) && (v) < (r))

// debug
#define DUMP(x) cerr << #x << " = " << (x)
#define DUMPLN(x) DUMP(x) << endl
#define DEBUG(x) DUMP(x) << LINE() << " " << __FILE__
#define DEBUGLN(x) DEBUG(x) << endl
#define LINE() cerr << " (L" << __LINE__ << ")"
#define LINELN() LINE() << endl
#define CHECK(exp, act)                                                        \
  if (exp != act) {                                                            \
    DUMPLN(exp);                                                               \
    DEBUGLN(act);                                                              \
  }
#define STOP(e)                                                                \
  CHECK(e, true);                                                              \
  if (!(e))                                                                    \
    exit(1);

class range {
private:
  struct Iter {
    int v;
    int operator*() { return v; }
    bool operator!=(Iter &itr) { return v < itr.v; }
    void operator++() { ++v; }
  };
  Iter i, n;

public:
  range(int n) : i({0}), n({n}) {}
  range(int i, int n) : i({i}), n({n}) {}
  Iter &begin() { return i; }
  Iter &end() { return n; }
};

// output
template <typename T> ostream &operator<<(ostream &os, const vector<T> &as) {
  REP(i, as.size()) {
    if (i != 0)
      os << " ";
    os << as[i];
  }
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const vector<vector<T>> &as) {
  REP(i, as.size()) {
    if (i != 0)
      os << endl;
    os << as[i];
  }
  return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &ss) {
  bool isF = true;
  for (auto &v : ss) {
    if (!isF)
      os << " ";
    os << v;
    isF = false;
  }
  return os;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
  os << p.first << " " << p.second;
  return os;
}
template <typename K, typename V>
ostream &operator<<(ostream &os, const map<K, V> &m) {
  bool isF = true;
  for (auto &p : m) {
    if (!isF)
      os << endl;
    os << p;
    isF = false;
  }
  return os;
}
template <typename T1> ostream &operator<<(ostream &os, const tuple<T1> &t) {
  os << get<0>(t);
  return os;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const tuple<T1, T2> &t) {
  os << get<0>(t) << " " << get<1>(t);
  return os;
}
template <typename T1, typename T2, typename T3>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3> &t) {
  os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t);
  return os;
}
template <typename T1, typename T2, typename T3, typename T4>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3, T4> &t) {
  os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " " << get<3>(t);
  return os;
}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3, T4, T5> &t) {
  os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " " << get<3>(t)
     << " " << get<4>(t);
  return os;
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
          typename T6>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3, T4, T5, T6> &t) {
  os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " " << get<3>(t)
     << " " << get<4>(t) << " " << get<5>(t);
  return os;
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
          typename T6, typename T7>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3, T4, T5, T6, T7> &t) {
  os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " " << get<3>(t)
     << " " << get<4>(t) << " " << get<5>(t) << " " << get<6>(t);
  return os;
}

// input
char tmp[1000];
#define nextInt(n) scanf("%d", &n)
#define nextLong(n) scanf("%lld", &n) // I64d
#define nextDouble(n) scanf("%lf", &n)
#define nextChar(n) scanf("%c", &n)
#define nextString(n)                                                          \
  scanf("%s", tmp);                                                            \
  n = tmp

// values
template <class T> T INF() { assert(false); };
template <> int INF<int>() { return 1 << 28; };
template <> ll INF<ll>() { return 1LL << 58; };
template <> double INF<double>() { return 1e16; };

namespace __scc {
typedef vector<vector<int>> Graph;
// O(V+E)
class Scc {
public:
  // private:
  int N;
  Graph g;
  vector<int> ord, low, cmp;
  vector<bool> vis;
  stack<int> st;
  vector<bool> S;
  int gi;
  void dfs(int v, int p, int &k) {
    vis[v] = true;
    ord[v] = k++;
    low[v] = ord[v];
    st.push(v);
    S[v] = true;
    for (int to : g[v]) {
      if (!vis[to]) {
        dfs(to, v, k);
        low[v] = min(low[v], low[to]);
      } else if (S[to]) {
        low[v] = min(low[v], ord[to]);
      }
    }
    if (low[v] != ord[v])
      return;
    while (st.top() != v) {
      cmp[st.top()] = gi;
      S[st.top()] = false;
      st.pop();
    }
    cmp[v] = gi;
    S[v] = false;
    st.pop();
    gi++;
  }

public:
  Scc(int N) : N(N) {
    g = Graph(N);
    ord = cmp = low = vector<int>(N, -1);
    vis = S = vector<bool>(N);
  }
  void add_edge(int f, int t) { g[f].push_back(t); }
  void scc() {
    int k = 0;
    gi = 0;
    REP(v, N) if (!vis[v]) dfs(v, -1, k);
  }
  bool same(int i, int j) { return cmp[i] == cmp[j]; }
};
} // namespace __scc
using namespace __scc;

class Main {
public:
  void run() {
    // include check
    int N, E;
    nextInt(N);
    nextInt(E);
    Scc g(N);
    REP(i, E) {
      int s, t;
      nextInt(s);
      nextInt(t);
      g.add_edge(s, t);
    }
    g.scc();
    // cerr << g.cmp <<endl;
    int Q;
    nextInt(Q);
    REP(q, Q) {
      int u, v;
      nextInt(u);
      nextInt(v);
      cout << (g.same(u, v) ? 1 : 0) << endl;
    }
  }
};

int main() {
  cout << fixed << setprecision(20);
  cin.tie(0);
  ios::sync_with_stdio(false);
  Main().run();
  return 0;
}