Pagini recente » Cod sursa (job #1326078) | Cod sursa (job #110460) | Cod sursa (job #1972137) | Cod sursa (job #3141368) | Cod sursa (job #1766390)
#include <bits/stdc++.h>
using namespace std;
const int kMaxN = 35005;
const int kMaxLog = 17;
int n, m, t, nScc;
vector <int> graph[kMaxN];
/** Strongly Connected Components and Tree */
int dfOrder;
int dfn[kMaxN];
int sccId[kMaxN];
bool onStack[kMaxN];
stack <int> sccStack;
vector <int> sccComp[kMaxN];
vector <int> sccTree[kMaxN];
int findScc(const int u) {
dfOrder++;
dfn[u] = dfOrder;
int minPtr = dfOrder;
sccStack.push(u);
onStack[u] = true;
for (const int v: graph[u]) {
if (!dfn[v]) {
minPtr = min(minPtr, findScc(v));
}
else if (onStack[v]) {
minPtr = min(minPtr, dfn[v]);
}
}
if (dfn[u] == minPtr) {
nScc++;
while (sccStack.top() != u) {
onStack[sccStack.top()] = false;
sccComp[nScc].push_back(sccStack.top());
sccId[sccStack.top()] = nScc;
sccStack.pop();
}
sccStack.pop();
onStack[u] = false;
sccComp[nScc].push_back(u);
sccId[u] = nScc;
}
return minPtr;
}
void buildSccTree() {
for (int i = 1; 2 * i <= nScc; i++) {
swap(sccComp[i], sccComp[nScc - i + 1]);
}
for (int i = 1; i <= n; i++) {
sccId[i] = nScc - sccId[i] + 1;
}
for (int i = 1; i <= nScc; i++) {
for (const int u: sccComp[i]) {
for (const int v: graph[u]) {
if (i != sccId[v]) {
sccTree[i].push_back(sccId[v]);
}
}
}
sort(sccTree[i].begin(), sccTree[i].end());
sccTree[i].erase(unique(sccTree[i].begin(), sccTree[i].end()), sccTree[i].end());
}
}
/** END Strongly Connected Components and Tree */
/** Tree Processing */
int depth[kMaxN];
int up[kMaxLog][kMaxN];
int anc[kMaxLog][kMaxN];
bool seen[kMaxN];
void dfsInit(const int u) {
seen[u] = true;
for (const int v: sccTree[u]) {
if (seen[v] == false) {
depth[v] = depth[u] + 1;
anc[0][v] = u;
up[0][v] = u;
dfsInit(v);
}
else if (depth[up[0][v]] > depth[u]) {
up[0][v] = u;
}
}
}
void dfsUp(const int u) {
seen[u] = false;
for (const int v: sccTree[u]) {
if (seen[v] == true) {
dfsUp(v);
if (depth[up[0][u]] > depth[up[0][v]]) {
up[0][u] = up[0][v];
}
}
}
}
void getAncestors() {
for (int i = 1; i < kMaxLog; i++) {
for (int j = 1; j <= nScc; j++) {
anc[i][j] = anc[i - 1][anc[i - 1][j]];
up[i][j] = up[i - 1][up[i - 1][j]];
}
}
}
int getLca(int x, int y) {
if (depth[x] < depth[y]) {
swap(x, y);
}
int d = depth[x] - depth[y];
for (int i = 0; (1 << i) <= d; i++) {
if ((d >> i) & 1) {
x = anc[i][x];
}
}
if (x == y) {
return x;
}
for (int i = kMaxLog - 1; i >= 0; i--) {
if (anc[i][x] != anc[i][y]) {
x = anc[i][x];
y = anc[i][y];
}
}
return anc[0][x];
}
/** END Tree Processing */
/** Preprocess */
void processGraph() {
findScc(1);
buildSccTree();
}
void processTree() {
depth[1] = 1;
anc[0][1] = 1;
up[0][1] = 1;
dfsInit(1);
dfsUp(1);
getAncestors();
}
/** END Preprocess */
int main() {
freopen("obiective.in", "r", stdin);
freopen("obiective.out", "w", stdout);
scanf("%d %d", &n, &m);
for (int i = 1; i <= m; i++) {
int u, v;
scanf("%d %d", &u, &v);
graph[u].push_back(v);
}
processGraph();
processTree();
int q;
for (scanf("%d", &q); q > 0; q--) {
int u, v;
scanf("%d %d", &u, &v);
u = sccId[u];
v = sccId[v];
const int x = getLca(u, v);
if (u == v || u == x) {
printf("0\n");
}
else {
int s = 0;
for (int i = kMaxLog - 1; i >= 0; i--) {
if (depth[up[i][u]] > depth[x]) {
u = up[i][u];
s |= 1 << i;
}
}
printf("%d\n", s + 1);
}
}
return 0;
}