Pagini recente » Cod sursa (job #2300561) | Cod sursa (job #1738533)
#include <bits/stdc++.h>
#define maxN 32002
#define maxM 64002
#define maxL 17
using namespace std;
int n, m, q;
int d[maxN], scc[maxN], C[maxN], nexti, c, f[maxN]; /// ctc
bool vis[maxN]; /// ctc
int anc[maxL][maxN], Log[maxM]; /// lca
vector < int > V[maxN], W[maxN], v[maxN];
bool used[maxN];
int Rmq[maxL][maxM], e, E[maxN];
void dfs_ctc(int x)
{
int i, l = V[x].size();
for (i = 0; i < l; ++ i)
if (!vis[V[x][i]])
{
vis[V[x][i]] = 1;
dfs_ctc(V[x][i]);
}
f[++ f[0]] = x;
}
void DFS(int x)
{
int i, l = W[x].size();
for (i = 0; i < l; ++ i)
if (!vis[W[x][i]])
{
vis[W[x][i]] = 1;
C[W[x][i]] = c;
DFS(W[x][i]);
}
}
void read()
{
int i;
freopen("obiective.in", "r", stdin);
scanf("%d %d", &n, &m);
for (i = 1; i <= m; ++ i)
{
int x, y;
scanf("%d %d", &x, &y);
V[x].push_back(y);
W[y].push_back(x);
}
}
void dfs(int x)
{
used[x] = 1;
int i, nod;
Rmq[0][++ e] = x;
E[x] = e;
sort(v[x].begin(), v[x].end());
for (i = 0; i < v[x].size(); ++ i)
if (!used[nod = v[x][i]])
{
dfs(nod);
Rmq[0][++ e] = nod;
anc[0][x] = min(anc[0][nod], anc[0][x]);
}
}
void solve()
{
int i, j;
for (i = 1; i <= n; ++ i)
if (!vis[i])
{
vis[i] = 1;
dfs_ctc(i);
}
memset(vis, 0, sizeof(vis));
for (i = n; i >= 1; -- i)
if (!vis[f[i]])
{
vis[f[i]] = 1;
C[f[i]] = ++ c;
DFS(f[i]);
}
for (i = 1; i <= c; ++ i)
anc[0][i] = i;
for (i = 1; i <= n; ++ i)
{
int nod, x = C[i], y;
for (j = 0; j < V[i].size(); ++ j)
{
y = C[nod = V[i][j]];
if (x == y)
continue;
v[x].push_back(y);
anc[0][y] = min(anc[0][y], x);
}
}
/*for (i = 1; i <= c; ++ i)
if (anc[0][i] == c + 1)
{
anc[0][i] = 0;
dfs(i);
}*/
dfs(1);
for (i = 2; i <= 2 * c; ++ i)
Log[i] = Log[i / 2] + 1;
for (j = 1; j < Log[e]; ++ j)
for (i = 1; i <= n; ++ i)
anc[j][i] = anc[j - 1][anc[j - 1][i]];
for (int i = 1; i <= Log[e]; ++i)
for (int j = 1; j <= e - (1 << i) + 1; ++j)
Rmq[i][j] = min(Rmq[i - 1][j], Rmq[i - 1][j + (1 << (i - 1))]);
}
int Lca(int x, int y)
{
x = E[x];
y = E[y];
if (x > y)
swap(x, y);
int k = Log[y - x];
return min(Rmq[k][x], Rmq[k][y - (1 << k) + 1]);
}
int Ans(int x, int l)
{
int i, ans = 0;
for (i = Log[c]; i >= 0; -- i)
if (anc[i][x] > l)
{
x = anc[i][x];
ans += 1 << i;
}
return ans + 1;
}
void write()
{
freopen("obiective.out", "w", stdout);
scanf("%d", &q);
while (q --)
{
int x, y;
scanf("%d %d", &x, &y);
x = C[x];
y = C[y];
int l = Lca(x, y);
if (x == l || x == y)
printf("%d\n", 0);
else
printf("%d\n", Ans(x, l));
}
}
int main()
{
read();
solve();
write();
return 0;
}