Problem:
Strongly Connected Components

A direced graph is strongly connected if every two nodes are reachable from each other. In a strongly connected component of a directed graph, every two nodes of the component are mutually reachable.

Input

A directed graph G(V, E) and a sequence of queries where each query contains a pair of nodes u and v.

|V| |E|
s0 t0
s1 t1
:
s|E|-1 t|E|-1
Q
u0 v0
u1 v1
:
uQ-1 vQ-1

|V| is the number of nodes and |E| is the number of edges in the graph. The graph nodes are named with the numbers 0, 1,..., |V|-1 respectively.

si and ti represent source and target nodes of i-th edge (directed).

ui and vi represent a pair of nodes given as the i-th query.

Output

For each query, pinrt "1" if the given nodes belong to the same strongly connected component, "0" otherwise.

Constraints

1 ≤ |V| ≤ 10,000

0 ≤ |E| ≤ 30,000

1 ≤ Q ≤ 100,000

Sample Input 1

5 6
0 1
1 0
1 2
2 4
4 3
3 2
4
0 1
0 3
2 3
3 4

Sample Output 1

1
0
1
1

Solution in C++ (judge verdict: Accepted)

#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;
 
int V,E;
 
vector<int> G[10000];
vector<int> reverse_G[10000];
stack<int> S;
 
int topo_rank[10000];
bool check[10000];
 
void dfs(int node_id){
    check[node_id] = true;
 
    for(int i = 0; i < G[node_id].size(); i++){
        if(!check[G[node_id][i]])dfs(G[node_id][i]);
    }
    S.push(node_id);
}
 
void reverse_dfs(int node_id,int num){
    check[node_id] = true;
    topo_rank[node_id] = num;
 
    for(int i = 0; i < reverse_G[node_id].size(); i++){
        if(!check[reverse_G[node_id][i]])reverse_dfs(reverse_G[node_id][i],num);
    }
}
 
 
int main(){
 
    scanf("%d %d",&V,&E);
 
    for(int i = 0; i < V;i++)check[i] = false;
 
    int from,to;
 
    for(int loop = 0; loop < E; loop++){
        scanf("%d %d",&from,&to);
        G[from].push_back(to);
        reverse_G[to].push_back(from);
    }
 
    for(int i = 0; i < V;i++){
        if(!check[i])dfs(i);
    }
 
    int num = 0;
 
    for(int i = 0; i < V;i++)check[i] = false;
 
    while(!S.empty()){
        if(!check[S.top()])reverse_dfs(S.top(),num++);
        S.pop();
    }
 
    int Q,left,right;
    scanf("%d",&Q);
 
    for(int loop = 0; loop < Q; loop++){
        scanf("%d %d",&left,&right);
        if(topo_rank[left] == topo_rank[right]){
            printf("1\n");
        }else{
            printf("0\n");
        }
    }
 
    return 0;
}