Pagini recente » Cod sursa (job #1263489) | Cod sursa (job #2586123) | Cod sursa (job #949696) | Cod sursa (job #2083475) | Cod sursa (job #1727397)
#include <fstream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <stack>
#include <map>
using namespace std;
ifstream fin("obiective.in");
ofstream fout("obiective.out");
const int dim = 32005;
const int dimLog = 17;
int n, m;
vector<int> g[dim];
int ctcCount, ctc[dim];
int low[dim], niv[dim], curNiv = 0;
stack<int> st;
void dfs(int node) {
niv[node] = low[node] = ++curNiv;
st.push(node);
for (auto& it : g[node]) {
if (niv[it] == 0)
dfs(it);
if (niv[it] > 0)
low[node] = min(low[node], low[it]);
}
if (low[node] == niv[node]) {
int x; ++ctcCount;
do {
x = st.top();
st.pop();
niv[x] *= -1;
ctc[x] = ctcCount;
} while (x != node);
}
}
map< pair<int, int>, bool> memo;
vector<int> ctcG[dim];
int parent[dimLog][dim];
void buildCtcGraph(void) {
for (int i = 1; i <= n; ++i)
ctc[i] = ctcCount - ctc[i] + 1;
for (int i = 1; i <= ctcCount; ++i)
parent[0][i] = i;
for (int i = 1; i <= n; ++i) {
for (auto& it : g[i]) {
if (ctc[i] == ctc[it] || memo[make_pair(ctc[i], ctc[it])])
continue;
memo[make_pair(ctc[i], ctc[it])] = true;
ctcG[ctc[i]].push_back(ctc[it]);
parent[0][ctc[it]] = min(parent[0][ctc[it]], ctc[i]);
}
}
}
void dfsCtcG(int node, int lvl) {
niv[node] = lvl;
for (auto& it : ctcG[node]) {
if (niv[it])
continue;
dfsCtcG(it, lvl + 1);
parent[0][node] = min(parent[0][node], parent[0][it]);
}
}
void initAnc(void) {
for (int i = 1; i < dimLog; ++i)
for (int j = 1; j <= ctcCount; ++j)
parent[i][j] = parent[i - 1][parent[i - 1][j]];
}
void goUp(int& x, int howMuch) {
for (int i = dimLog - 1; i >= 0; --i)
if ((1 << i) <= howMuch)
howMuch -= (1 << i), x = parent[i][x];
}
int lca(int x, int y) {
if (niv[x] < niv[y])
swap(x, y);
goUp(x, niv[x] - niv[y]);
if (x == y)
return x;
for (int i = dimLog - 1; i >= 0; --i) {
if (parent[i][x] == parent[i][y])
continue;
x = parent[i][x];
y = parent[i][y];
}
x = parent[0][x];
return x;
}
int main() {
fin >> n >> m;
for (int i = 1; i <= m; ++i) {
int x, y; fin >> x >> y;
g[x].push_back(y);
}
for (int i = 1; i <= n; ++i)
if (niv[i] == 0)
dfs(i);
buildCtcGraph();
memset(niv, 0, sizeof niv);
dfsCtcG(1, 1);
initAnc();
int t; fin >> t;
while (t--) {
int x, y; fin >> x >> y;
x = ctc[x], y = ctc[y];
int z = lca(x, y);
if (x == z) {
fout << "0\n";
continue;
}
int sol = 1;
for (int i = dimLog - 1; i >= 0; --i)
if (parent[i][x] > z)
sol += (1 << i), x = parent[i][x];
fout << sol << '\n';
}
return 0;
}
//Trust me, I'm the Doctor!