Pagini recente » Cod sursa (job #2303835) | Cod sursa (job #630967) | Cod sursa (job #129403) | Cod sursa (job #606433) | Cod sursa (job #1766412)
#include <bits/stdc++.h>
using namespace std;
const int kMaxN = 35005;
const int kMaxLog = 17;
int n, m, t, nScc;
vector <int> graph[kMaxN];
vector <int> grapht[kMaxN];
/** Strongly Connected Components and Tree */
stack <int> kosStack;
vector <int> tree[kMaxN];
int sccId[kMaxN];
int order[kMaxN];
bool seen[kMaxN];
int topsPtr;
void fiKosaraju(const int u) {
seen[u] = true;
for (const int v: graph[u]) {
if (!seen[v]) {
fiKosaraju(v);
}
}
kosStack.push(u);
}
void seKosaraju(const int u, const int c) {
seen[u] = false;
sccId[u] = c;
for (const int v: grapht[u]) {
if (seen[v]) {
seKosaraju(v, c);
}
}
}
void findScc() {
for (int i = 1; i <= n; i++) {
if (!seen[i]) {
fiKosaraju(i);
}
}
while (!kosStack.empty()) {
if (seen[kosStack.top()]) {
nScc++;
seKosaraju(kosStack.top(), nScc);
}
kosStack.pop();
}
}
void topSort(const int u) {
seen[u] = true;
for (const int v: tree[u]) {
if (!seen[v]) {
topSort(v);
}
}
order[++topsPtr] = u;
}
void buildSccTree() {
for (int i = 1; i <= n; i++) {
for (const int u: graph[i]) {
if (sccId[i] != sccId[u]) {
tree[sccId[i]].push_back(sccId[u]);
}
}
}
topSort(1);
for (int i = 1; i <= nScc; i++) {
sort(tree[i].begin(), tree[i].end(), [] (const int x, const int y) { return order[x] > order[y]; });
}
}
/** END Strongly Connected Components and Tree */
/** Tree Processing */
int depth[kMaxN];
int up[kMaxLog][kMaxN];
int anc[kMaxLog][kMaxN];
void dfsInit(const int u) {
seen[u] = false;
for (const int v: tree[u]) {
if (seen[v] == true) {
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] = true;
for (const int v: tree[u]) {
if (seen[v] == false) {
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();
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);
grapht[v].push_back(u);
}
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;
}