Pagini recente » Cod sursa (job #2536856) | Cod sursa (job #1780066) | Cod sursa (job #2026305) | Cod sursa (job #431692) | Cod sursa (job #2394744)
/// By Alexa Tudose (Alexa2001)
/// Just I'm looking, not I'm stealing : )
#include <bits/stdc++.h>
using namespace std;
ifstream fin ("obiective.in");
ofstream fout ("obiective.out");
const int Nmax = 33000, lg = 16;
int n, m, nr, ordsz;
int where[Nmax], ord[Nmax], level[Nmax];
int t[lg+2][Nmax], up[lg+2][Nmax];
vector<int> v[Nmax], vt[Nmax], edge[Nmax];
bool used[Nmax];
void dfs(int node)
{
int i,vecin,t;
used[node] = 1;
t=v[node].size();
for(i=0;i<t;++i)
{
vecin=v[node][i];
if(!used[vecin]) dfs(vecin);
}
ord[++ordsz] = node;
}
void dfs2(int node)
{
int i,vecin,t;
where[node] = nr;t=vt[node].size();
for(i=0;i<t;++i)
{
vecin=vt[node][i];
if(!where[vecin]) dfs2(vecin);
}
}
void init()
{
int i, x, y;
fin >> n >> m;
for(i=1; i<=m; ++i)
{
fin >> x >> y;
v[x].push_back(y);
vt[y].push_back(x);
}
for(i=1; i<=n; ++i)
if(!used[i]) dfs(i);
for(i=ordsz; i; --i)
if(!where[ord[i]])
{
++nr;
dfs2(ord[i]);
}
int t,vecin,j;
for(i=1; i<=n; ++i)
{
t=v[i].size();
for(j=0;j<t;++j)
{
vecin=v[i][j];
if(where[vecin] != where[i])
edge[where[i]].push_back(where[vecin]);
}
}
}
void dfs3(int node, int dad = 0)
{
t[0][node] = dad;
level[node] = level[dad] + 1;
up[0][node] = dad;
int t,vecin,j;
t=edge[node].size();
for(j=0;j<t;++j)
{
vecin=edge[node][j];
if(!level[vecin])
dfs3(vecin, node);
else up[0][vecin] = min(up[0][vecin], node);
}
}
void precompute()
{
int i, j;
for(i=1; i<=nr; ++i) sort(edge[i].begin(), edge[i].end());
/*for(i=1;i<=nr;++i,fout<<"\n")
{
fout<<i<<": ";
for(j=0;j<edge[i].size();++j)fout<<edge[i][j]<<" ";
}*/
dfs3(1);
///for(i=nr; i; --i) up[0][t[0][i]] = min(up[0][t[0][i]], up[0][i]);
for(i=1; i<=lg; ++i)
for(j=1; j<=nr; ++j)
{
t[i][j] = t[i-1][t[i-1][j]];
up[i][j] = up[i-1][up[i-1][j]];
}
}
int lca(int x, int y)
{
if(level[x] < level[y]) swap(x, y);
int up = level[x] - level[y], i;
for(i=0; i<=lg; ++i)
if(up & (1<<i)) x = t[i][x];
if(x == y) return x;
for(i=lg; i>=0; --i)
if(t[i][x] != t[i][y])
x = t[i][x], y = t[i][y];
return t[0][x];
}
int goo(int node, int lim)
{
if(node == lim) return 0;
int i, ans = 0;
for(i=lg; i>=0; --i)
if(level[up[i][node]] > level[lim]) ans += (1<<i), node = up[i][node];
return ans + 1;
}
void solve_queries()
{
int x, y, q, L;
fin >> q;
while(q--)
{
fin >> x >> y;
x = where[x]; y = where[y];
L = lca(x, y);
fout << goo(x, L) << '\n';
}
}
int main()
{
init();
precompute();
solve_queries();
return 0;
}