Pagini recente » Cod sursa (job #3240534) | Cod sursa (job #2976248) | Cod sursa (job #2770083) | Cod sursa (job #2126277) | Cod sursa (job #2976257)
#include <bits/stdc++.h>
//#pragma GCC optimize ("03")
#define FastIO ios_base::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define FILES freopen("obiective.in" , "r" , stdin) , freopen("obiective.out" , "w" , stdout)
#define ll long long
#define ull unsigned long long
#define ld long double
#define eb emplace_back
#define pb push_back
#define qwerty1 first
#define qwerty2 second
#define qwerty3 -> first
#define qwerty4 -> second
#define umap unordered_map
#define uset unordered_set
#define pii pair < ll , ll >
#define pq priority_queue
#define dbg(x) cerr << #x << ": " << x << '\n'
namespace FastRead
{
char __buff[5000];ll __lg = 0 , __p = 0;
char nc()
{
if(__lg == __p){__lg = fread(__buff , 1 , 5000 , stdin);__p = 0;if(!__lg) return EOF;}
return __buff[__p++];
}
template<class T>void read(T&__x)
{
T __sgn = 1; char __c;while(!isdigit(__c = nc()))if(__c == '-')__sgn = -1;
__x = __c - '0';while(isdigit(__c = nc()))__x = __x * 10 + __c - '0';__x *= __sgn;
}
}
using namespace FastRead;
using namespace std;
const ll N = 32e3 + 10;
const ll M = 1e9 + 7;
const ld PI = acos(-1);
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int n , m;
stack < int > st;
vector < int > G[N] , g[N] , ctc[N] , GC[N];
int mark[N] , in[N] , gr[N] , height[N] , rmq[N][20];
int cnt = 0;
void dfs(int node)
{
mark[node] = 1;
for(auto to : G[node])
if(!mark[to])
dfs(to);
st.push(node);
}
void dfs2(int node)
{
ctc[cnt].pb(node);
gr[node] = cnt;
mark[node] = 2;
for(auto to : g[node])
if(mark[to] == 1)
dfs2(to);
}
int lca(int x , int y)
{
if(height[x] < height[y])
swap(x , y);
int delta = height[x] - height[y];
for(int bit = 0 ; bit <= 15 ; bit++)
if(delta >> bit & 1)
x = rmq[x][bit];
if(x == y)
return x;
for(int bit = 15 ; bit >= 0 ; bit--)
if(rmq[x][bit] != rmq[y][bit])
{
x = rmq[x][bit];
y = rmq[y][bit];
}
return rmq[x][0];
}
signed main()
{
#ifndef ONLINE_JUDGE
FastIO , FILES;
#endif
int i , j;
cin >> n >> m;
while(m--)
{
int x , y;
cin >> x >> y;
G[x].pb(y);
g[y].pb(x);
}
for(i = 1 ; i <= n ; i++)
if(!mark[i])
dfs(i);
while(!st.empty())
{
int node = st.top();
st.pop();
if(mark[node] == 1)
{
++cnt;
dfs2(node);
}
}
for(i = 1 ; i <= n ; i++)
for(auto j : G[i])
if(gr[i] != gr[j])
{
++in[gr[j]];
GC[gr[i]].pb(gr[j]);
}
queue < int > q;
for(i = 1 ; i <= cnt ; i++)
if(!in[i])
q.push(i) , height[i] = 1;
while(!q.empty())
{
int node = q.front();
q.pop();
for(auto to : GC[node])
{
if(height[to] == 0)
{
height[to] = height[node] + 1;
rmq[to][0] = node;
}
if(--in[to] == 0)
q.push(to);
}
}
for(j = 1 ; (1 << j) <= cnt ; j++)
for(i = 1 ; i <= cnt ; i++)
rmq[i][j] = rmq[rmq[i][j - 1]][j - 1];
int Q;
cin >> Q;
while(Q--)
{
int x , y;
cin >> x >> y;
x = gr[x];
y = gr[y];
if(x == y)
{
cout << 0 << '\n';
continue;
}
int L = lca(x , y);
if(L == x)
{
cout << 0 << '\n';
continue;
}
for(int bit = 15 ; bit >= 0 ; bit--)
if(height[rmq[x][bit]] > height[L])
{
ans += (1 << bit);
x = rmq[x][bit];
}
cout << ans + 1 << '\n';
}
return 0;
}