Pagini recente » Cod sursa (job #3030879) | Cod sursa (job #1387321) | Cod sursa (job #202563) | Cod sursa (job #363550) | Cod sursa (job #2147941)
#include <fstream>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
ifstream fin ("obiective.in"); ofstream fout ("obiective.out");
const int nmax = 32e3;
const int logmax = 14;
const int inf = 1 << 30;
int n, nrc, rad;
bool viz[nmax + 1], grnenul[nmax + 1];
int comp[nmax + 1];
vector< int > ord, g[ 2 ][nmax + 1];
int h[nmax + 1], link[nmax + 1];
int d[logmax + 1][nmax + 1];
int l[logmax + 1][nmax + 1];
vector< int > gc[nmax + 1];
void dfs_ctc (int nod, int ind) {
viz[ nod ] = 1;
if (ind == 1)
comp[ nod ] = nrc;
for (auto i : g[ ind ][ nod ]) {
if (viz[ i ] == 0) {
dfs_ctc (i, ind);
}
}
if (ind == 0)
ord.push_back( nod );
}
void ctc () {
for (int i = 1; i <= n; ++ i) {
if (viz[ i ] == 0)
dfs_ctc (i, 0);
}
memset(viz, 0, sizeof(viz));
reverse(ord.begin(), ord.end());
for (auto i : ord) {
if (viz[ i ] == 0) {
++ nrc;
dfs_ctc (i, 1);
}
}
}
void trage_muchii_ctc () {
for (int i = 1; i <= n; ++ i) {
for (auto j : g[ 0 ][ i ]) {
if (comp[ i ] != comp[ j ]) {
gc[ comp[ i ] ].push_back(comp[ j ]);
grnenul[ comp[ j ] ] = 1;
}
}
}
for (int i = 1; i <= nrc; ++ i) {
sort(gc[ i ].begin(), gc[ i ].end());
gc[ i ].erase(unique(gc[ i ].begin(), gc[ i ].end()), gc[ i ].end());
if (grnenul[ i ] == 0)
rad = i;
}
}
void dfs (int nod) {
viz[ nod ] = 1;
for (auto i : gc[ nod ]) {
if (link[ i ] == 0 || h[ link[ i ] ] > h[ nod ]) {
link[ i ] = nod;
}
}
for (auto i : gc[ nod ]) {
if (viz[ i ] == 0) {
d[ 0 ][ i ] = nod;
h[ i ] = h[ nod ] + 1;
dfs( i );
if (link[ nod ] == 0 || h[ link[ nod ] ] > h[ link[ i ] ]) {
link[ nod ] = link[ i ];
}
}
}
}
void precalc () {
for (int i = 1; (1 << i) <= nrc; ++ i) {
for (int j = 1; j <= nrc; ++ j) {
d[ i ][ j ] = d[i - 1][ d[i - 1][ j ] ];
}
}
for (int i = 1; i <= nrc; ++ i)
l[ 0 ][ i ] = link[ i ];
for (int i = 1; (1 << i) <= nrc; ++ i) {
for (int j = 1; j <= nrc; ++ j) {
l[ i ][ j ] = l[i - 1][ l[i - 1][ j ] ];
}
}
}
int lca_query (int x, int y) {
if (h[ x ] > h[ y ])
swap(x, y);
int dif = h[ y ] - h[ x ];
for (int i = logmax; i >= 0; -- i) {
if (dif & (1 << i))
y = d[ i ][ y ];
}
for (int i = logmax; i >= 0; -- i) {
if (d[ i ][ x ] != d[ i ][ y ]) {
x = d[ i ][ x ];
y = d[ i ][ y ];
}
}
if (x != y)
x = d[ 0 ][ x ];
return x;
}
int main () {
int m;
fin >> n >> m;
for (int i = 1; i <= m; ++ i) {
int x, y;
fin >> x >> y;
g[ 0 ][ x ].push_back( y );
g[ 1 ][ y ].push_back( x );
}
ctc ();
trage_muchii_ctc ();
memset(viz, 0, sizeof(viz));
dfs( rad );
precalc ();
int t;
fin >> t;
for (int i = 1; i <= t; ++ i) {
int x, y;
fin >> x >> y;
x = comp[ x ], y = comp[ y ];
int lim = h[ lca_query(x, y) ];
int ans = 0;
for (int j = logmax; j >= 0; -- j) {
if (h[ l[ j ][ x ] ] > lim) {
x = l[ j ][ x ];
ans += (1 << j);
}
}
if (h[ x ] > lim)
++ ans;
fout << ans << "\n";
}
fin.close();
fout.close();
return 0;
}