Pagini recente » Cod sursa (job #2901713) | Cod sursa (job #2494720) | Cod sursa (job #433947) | Cod sursa (job #1065473) | Cod sursa (job #2500046)
#include <fstream>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int NMAX=32005;
vector <int> graph[NMAX];
vector <int> graph_inv[NMAX];
int _stack[NMAX];
int _stack_size;
int i;
bool vis[NMAX];
void dfs_inv (int node)
{
vis[node]=true;
for (auto it: graph_inv[node])
if (!vis[it])
dfs_inv(it);
_stack[++ _stack_size]=node;
}
int which_scc[NMAX];
void dfs (int node, int scc)
{
vis[node]=true;
which_scc[node]=scc;
for (auto it: graph[node])
if (!vis[it])
dfs(it, scc);
}
vector <int> new_graph[NMAX];
vector <int> tree_graph[NMAX];
int degs[NMAX];
int h[NMAX];
int fathers[15][NMAX];
void dfs_lca (int node)
{
h[node] = h[fathers[0][node]]+1;
for (i=1; i<15; ++i)
fathers[i][node]=fathers[i-1][fathers[i - 1][node]];
for (auto it: tree_graph[node])
{
fathers[0][it]=node;
dfs_lca(it);
}
}
int lca (int a, int b)
{
if (h[a]>h[b])
swap(a, b);
for (i=14; i>=0; --i)
if (h[fathers[i][b]]>=h[a])
b=fathers[i][b];
if(a==b)
return a;
for (i=14; i>=0; --i)
if (fathers[i][a] != fathers[i][b])
{
a=fathers[i][a];
b=fathers[i][b];
}
return fathers[0][a];
}
int sus[15][NMAX];
void dfs_sus0 (int node) {
for (auto it: tree_graph[node]) {
dfs_sus0(it);
if (h[sus[0][it]] < h[sus[0][node]])
sus[0][node] = sus[0][it];
}
}
void dfs_sus (int node)
{
for (int i=1; i<15; ++i)
sus[i][node] = sus[i - 1][sus[i - 1][node]];
for (auto it: tree_graph[node])
dfs_sus(it);
}
int query (int a, int l)
{
int ans=0;
if (a==l)
return 0;
for(i=14; i>=0; --i)
if (h[sus[i][a]]>h[l])
{
a=sus[i][a];
ans+=(1<<i);
}
return 1+ans;
}
int main()
{
ifstream cin("obiective.in");
ofstream cout("obiective.out");
int n=0, m=0;
cin>>n>>m;
int a,b;
while(m--)
{
cin>>a>>b;
graph[a].push_back(b);
graph_inv[b].push_back(a);
}
for(i=1; i<=n; ++i)
if(!vis[i])
dfs_inv(i);
memset(vis, 0, sizeof(vis));
int sccs=0;
for (int i=n; i; --i)
if (!vis[_stack[i]])
dfs(_stack[i], ++sccs);
for(i=1; i<=n; ++i)
for (auto it: graph[i])
if (which_scc[i] != which_scc[it])
new_graph[which_scc[i]].push_back(which_scc[it]);
n=sccs;
for(i=1; i<=n; ++i)
for(auto it:new_graph[i])
{
if (!degs[it])
{
++degs[it];
tree_graph[i].push_back(it);
}
}
dfs_lca(n);
for(i=1; i<=n; ++i)
sus[0][i]=i;
for(i=1; i<=n; ++i)
for(auto it: new_graph[i])
if (h[i]<h[sus[0][it]])
sus[0][it]=i;
dfs_sus0(n);
dfs_sus(n);
int q=0;
cin>>q;
int l;
while(q--)
{
cin>>a>>b;
a=which_scc[a], b = which_scc[b];
l=lca(a, b);
cout<<query(a,l)<<'\n';
}
return 0;
}