Pagini recente » Cod sursa (job #2886338) | Cod sursa (job #3132266) | Cod sursa (job #2347698) | Cod sursa (job #2252065) | Cod sursa (job #2922482)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("obiective.in");
ofstream fout("obiective.out");
const int kN = 1 << 15;
const int kLog = 16;
const int INF = 1e9;
int timer, N, tin[kN], low[kN], ctcIndex[kN], dep[kN], in[kN], out[kN], lg2[kN], anc[kN][kLog], lift[kN][kLog];
vector<int> stk, g[kN], G[kN];
bitset<kN> vis;
void minSelf(int &x, int y) {
if (y < x) {
x = y;
}
}
void dfsCTC(int u) {
tin[u] = ++timer;
low[u] = timer;
stk.emplace_back(u);
for (int v : g[u]) {
if (tin[v]) {
minSelf(low[u], tin[v]);
} else {
dfsCTC(v);
minSelf(low[u], low[v]);
}
}
if (tin[u] == low[u]) {
N += 1;
int node;
do {
node = stk.back();
stk.pop_back();
tin[node] = INF;
ctcIndex[node] = N;
} while (node != u);
}
}
void dfsT(int u, int par) {
vis[u] = true;
dep[u] = dep[par] + 1;
anc[u][0] = par;
lift[u][0] = par;
in[u] = ++timer;
for (int v : G[u]) {
if (vis[v]) {
minSelf(lift[v][0], u);
} else {
dfsT(v, u);
}
}
out[u] = timer;
}
bool isAnc(int u, int v) {
return in[u] <= in[v] && out[v] <= out[u];
}
int lca(int u, int v) {
if (dep[u] < dep[v]) {
swap(u, v);
}
if (isAnc(v, u)) {
return v;
}
for (int i = lg2[dep[v]]; i >= 0; --i) {
if (anc[v][i] && !isAnc(anc[v][i], u)) {
v = anc[v][i];
}
}
return anc[v][0];
}
int solve(int v, int d) {
if (dep[v] <= d) {
return 0;
}
int res = 1;
for (int i = lg2[dep[v]]; i >= 0; --i) {
if (dep[lift[v][i]] > d) {
res += (1 << i);
v = lift[v][i];
}
}
return res;
}
int main() {
int n, m;
fin >> n >> m;
for (int i = 0; i < m; ++i) {
int u, v;
fin >> u >> v;
g[u].emplace_back(v);
}
for (int v = 1; v <= n; ++v) {
if (!tin[v]) {
dfsCTC(v);
}
}
for (int v = 1; v <= n; ++v) {
ctcIndex[v] = N - ctcIndex[v] + 1;
}
for (int u = 1; u <= n; ++u) {
for (int v : g[u]) {
if (ctcIndex[u] != ctcIndex[v]) {
G[ctcIndex[u]].emplace_back(ctcIndex[v]);
}
}
}
for (int v = 1; v <= N; ++v) {
sort(G[v].begin(), G[v].end());
G[v].erase(unique(G[v].begin(), G[v].end()), G[v].end());
}
timer = 0;
for (int v = 1; v <= N; ++v) {
if (!vis[v]) {
dfsT(v, 0);
}
}
for (int v = N; v > 0; --v) {
minSelf(lift[anc[v][0]][0], lift[v][0]);
}
for (int i = 1; i < kLog; ++i) {
for (int v = 1; v <= N; ++v) {
anc[v][i] = anc[anc[v][i - 1]][i - 1];
lift[v][i] = lift[lift[v][i - 1]][i - 1];
}
}
for (int i = 2; i <= N; ++i) {
lg2[i] = lg2[i / 2] + 1;
}
int q;
fin >> q;
for (int i = 0; i < q; ++i) {
int u, v;
fin >> u >> v;
u = ctcIndex[u];
v = ctcIndex[v];
int l = lca(u, v);
fout << solve(u, dep[l]) << '\n';
}
fin.close();
fout.close();
return 0;
}