Pagini recente » Cod sursa (job #1736798) | Cod sursa (job #1115741) | Cod sursa (job #1510231) | Cod sursa (job #1005917) | Cod sursa (job #2105439)
#include <bits/stdc++.h>
using namespace std;
int const N = 32000 + 2;
int n, m, t;
vector<int>G[N], T[N];
int wscc[N], sccind;
bool vis[N];
vector<int>order;
vector<int>sccG[N];
int prv[N];
vector<int>TreeG[N];
int anc[17][N], dep[N];
int best[17][N];
void dfs(int x) {
vis[x] = 1;
for(int y : G[x]) if(!vis[y]) dfs(y);
order.push_back(x);
}
void dfs2(int x) {
vis[x] = 1;
wscc[x] = sccind;
for(int y : T[x])
if(!vis[y]) dfs2(y);
}
int lca(int x, int y) {
if(dep[x] < dep[y]) swap(x, y);
for(int i = 15; i >= 0; --i) if(dep[x] - (1 << i) >= dep[y]) x = anc[i][x];
if(x == y) return x;
for(int i = 15; i >= 0; --i) if(anc[i][x] > 0 && anc[i][y] > 0 && anc[i][x] != anc[i][y]) x = anc[i][x], y = anc[i][y];
return anc[0][x];
}
int qry(int x, int y) {
int up = lca(x, y);
if(x == up) return 0;
int ret = 0;
for(int i = 15; i >= 0; --i) {
if(dep[best[i][x]] > dep[up]) {
ret += 1 << i;
x = best[i][x];
}
}
return ret + 1;
}
void tdfs(int x) {
vis[x] = 1;
for(int y : sccG[x]) {
if(!vis[y]) {
TreeG[x].push_back(y);
dep[y] = dep[x] + 1;
anc[0][y] = min(anc[0][y], x);
best[0][y] = min(best[0][y], x);
tdfs(y);
} else {
anc[0][x] = min(anc[0][x], y);
best[0][x] = min(best[0][x], y);
}
}
}
void dfsup(int x) {
for(int y : TreeG[x]) {
dfsup(y);
best[0][x] = min(best[0][x], best[0][y]);
}
}
void findsccs() {
for(int i = 1; i <= n; ++i) if(!vis[i]) dfs(i);
fill(vis + 1, vis + n + 1, 0);
for(int i = order.size() - 1; i >= 0; --i) {
if(!vis[order[i]]) {
++sccind;
dfs2(order[i]);
}
}
for(int i = 1; i <= sccind; ++i)
anc[0][i] = n + 1, best[0][i] = i;
for(int j = 1; (1 << j) <= sccind; ++j)for(int i = 1; i <= n; ++i)best[j][i] = i;
for(int i = 1; i <= n; ++i) {
for(int j : G[i]) {
if(wscc[i] != wscc[j]) {
int ci = wscc[i], cj = wscc[j];
sccG[ci].push_back(cj);
}
}
}
for(int i = 1; i <= n; ++i)sort(sccG[i].begin(), sccG[i].end());
fill(vis + 1, vis + n + 1, 0);
anc[0][1] = 0;
dep[1] = 1;
tdfs(1);
dfsup(1);
for(int p = 1; (1 << p) <= sccind; ++p) {
for(int i = 1; i <= sccind; ++i) {
anc[p][i] = anc[p - 1][anc[p - 1][i]];
best[p][i] = min(best[p - 1][i], best[p - 1][best[p - 1][i]]);
}
}
}
int main() {
ifstream cin("obiective.in");
ofstream cout("obiective.out");
cin >> n >> m;
for(int i = 1; i <= m; ++i) {
int x, y;
cin >> x >> y;
G[x].push_back(y);
T[y].push_back(x);
}
cin >> t;
findsccs();
while(t--) {
int x, y;
cin >> x >> y;
x = wscc[x];
y = wscc[y];
cout << qry(x, y) << '\n';
}
}