This documentation is automatically generated by online-judge-tools/verification-helper
#define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_3_C"
#include "../../graph/strongly-connected-components.hpp"
#include <iostream>
using namespace std;
int main() {
int V, E;
cin >> V >> E;
Graph<int> graph(V);
for (int i = 0; i < E; ++i) {
int x, y;
cin >> x >> y;
graph[x].emplace_back(x, y);
}
stronglyConnectedComponents<int> scc(graph);
scc.build();
int Q;
cin >> Q;
for (int i = 0; i < Q; ++i) {
int u, v;
cin >> u >> v;
if (scc.same(u, v)) { cout << "1" << endl; }
else { cout << "0" << endl; }
}
}
#line 1 "test/aoj/GRL_3_C.test.cpp"
#define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_3_C"
#line 1 "graph/strongly-connected-components.hpp"
// @title 強連結成分分解
#include <cassert>
#include <algorithm>
#include <vector>
#line 1 "graph/template.hpp"
#include <iostream>
#line 6 "graph/template.hpp"
template< typename T >
struct Edge {
int from, to;
T cost;
Edge() {}
Edge(int f, int t) : from(f), to(t), cost(1) {}
Edge(int f, int t, T c) : from(f), to(t), cost(c) {}
friend bool operator < (const Edge& lhs, const Edge& rhs) { return lhs.cost < rhs.cost; };
friend bool operator > (const Edge& lhs, const Edge& rhs) { return rhs < lhs; };
friend bool operator <= (const Edge& lhs, const Edge& rhs) { return !(lhs > rhs); };
friend bool operator >= (const Edge& lhs, const Edge& rhs) { return !(lhs < rhs); };
};
template< typename T >
using Edges = std::vector< Edge< T > >;
template< typename T >
using Graph = std::vector< Edges< T > >;
template< typename T >
void debug(Graph<T> &g, int n = -1) {
if (n == -1) n = g.size();
for (int i = 0; i < n; ++i) {
std::cerr << i << "\t";
for (auto &e: g[i]) {
std::cerr << e.to << ",";
}
std::cerr << std::endl;
}
}
#line 9 "graph/strongly-connected-components.hpp"
using namespace std;
template< typename T >
struct stronglyConnectedComponents {
using graph = Graph<T>;
const int V;
graph g, rg;
vector<bool> visit;
vector<int> comp, order;
vector<vector<int>> components;
stronglyConnectedComponents(const graph &g) : V(g.size()), g(g), rg(V), visit(V, false), comp(V, -1) {
// 辺の向きを逆にしたグラフを構築
for (int v = 0; v < V; ++v) {
for (auto &e : g[v]) {
rg[e.to].emplace_back(e.to, e.from);
}
}
}
// 同じ強連結成分に属していればtrueを返す
bool same(int s, int t) {
assert(comp[s] != -1 && comp[t] != -1);
return comp[s] == comp[t];
}
void dfs(int sv) {
if (visit[sv]) return;
visit[sv] = true;
for (auto &e : g[sv]) {
dfs(e.to);
}
order.push_back(sv);
}
void rdfs(int sv, int cnt) {
if (comp[sv] != -1) return;
comp[sv] = cnt;
if (components.size() <= cnt) {
vector<int> v;
components.push_back(v);
}
components[cnt].push_back(sv);
for (auto &e : rg[sv]) {
rdfs(e.to, cnt);
}
}
void build() {
for(int i = 0; i < V; i++) { dfs(i); }
assert(order.size() == V);
reverse(order.begin(), order.end()); // dfsでつけた番号を逆順にする
int cnt = 0; // 強連結成分毎のid
for (int v : order) {
if (comp[v] != -1) continue;
rdfs(v, cnt);
// 強連結成分の頂点をループの順に並び替え
if (components[cnt].size() > 1) {
reverse(components[cnt].begin()+1, components[cnt].end());
}
++cnt;
}
}
};
#line 5 "test/aoj/GRL_3_C.test.cpp"
using namespace std;
int main() {
int V, E;
cin >> V >> E;
Graph<int> graph(V);
for (int i = 0; i < E; ++i) {
int x, y;
cin >> x >> y;
graph[x].emplace_back(x, y);
}
stronglyConnectedComponents<int> scc(graph);
scc.build();
int Q;
cin >> Q;
for (int i = 0; i < Q; ++i) {
int u, v;
cin >> u >> v;
if (scc.same(u, v)) { cout << "1" << endl; }
else { cout << "0" << endl; }
}
}