Pagini recente » Cod sursa (job #2835493) | Cod sursa (job #535140) | Cod sursa (job #681822) | Cod sursa (job #2522522) | Cod sursa (job #3121342)
#include <fstream>
#include <vector>
#include <stack>
#include <set>
using namespace std;
ifstream fin( "obiective.in" );
ofstream fout( "obiective.out" );
const int MAXN = 32e3;
const int MAXLOG = 17;
const int INF = 2e9;
stack<int> srt;
set<int> dag[ MAXN + 1 ];
vector<int> g[ MAXN + 1 ];
vector<int> gt[ MAXN + 1 ];
int rmq[ MAXLOG + 1 ][ 2 * MAXN + 1 ];
int anc[ MAXLOG + 1 ][ MAXN + 1 ];
int comptc[ MAXN + 1 ];
int lg[ 2 * MAXN + 1 ];
bool seen[ MAXN + 1 ];
int prim[ MAXN + 1 ];
int comptc_num;
int euler_num;
void norm_dfs( int node ) {
seen[ node ] = true;
for( auto it : g[ node ] )
if( seen[ it ] == false )
norm_dfs( it );
srt.push( node );
}
void rev_dfs( int node ) {
seen[ node ] = false;
comptc[ node ] = comptc_num;
for( auto it : gt[ node ] )
if( seen[ it ] )
rev_dfs( it );
}
void euler_traversal( int node ) {
seen[ node ] = true;
prim[ node ] = ++euler_num;
rmq[ 0 ][ euler_num ] = node;
for( auto it : dag[ node ] )
if( seen[ it ] == 0 ) {
euler_traversal( it );
rmq[ 0 ][ ++euler_num ] = node;
anc[ 0 ][ node ] = min( anc[ 0 ][ node ], anc[ 0 ][ it ] );
}
}
int low_com_anc( int u, int v ) {
if( prim[ u ] > prim[ v ] )
swap( u, v );
int aux = lg[ prim[ v ] - prim[ u ] ];
return min( rmq[ aux ][ prim[ u ] ], rmq[ aux ][ prim[ v ] - ( 1 << aux ) + 1 ] );
}
int main()
{
int n, m, x, y, t, lca, rez;
for( int i = 2; i <= 2 * MAXN; ++i )
lg[ i ] = lg[ i / 2 ] + 1;
fin >> n >> m;
for( int i = 0; i < m; i++ ) {
fin >> x >> y;
g[ x ].push_back( y );
gt[ y ].push_back( x );
}
for( int i = 1; i <= n; i++ )
if( seen[ i ] == false )
norm_dfs( i );
while( srt.empty() == 0 ) {
if( seen[ srt.top() ] ) {
++comptc_num;
rev_dfs( srt.top() );
}
srt.pop();
}
for( int i = 1; i <= n; i++ )
anc[ 0 ][ i ] = INF;
for( int i = 1; i <= n; i++ ) {
x = comptc[ i ];
for( auto it : g[ i ] )
if( x != comptc[ it ] ) {
y = comptc[ it ];
dag[ x ].insert( y );
anc[ 0 ][ y ] = min( anc[ 0 ][ y ], x );
}
}
euler_traversal( 1 );
for( int i = 1; i <= lg[ euler_num ]; i++ ) {
for( int j = 1; j <= comptc_num; j++ )
anc[ i ][ j ] = anc[ i - 1 ][ anc[ i - 1 ][ j ] ];
for( int j = 1; j <= euler_num - ( 1 << i ) + 1; j++ )
rmq[ i ][ j ] = min( rmq[ i - 1 ][ j ], rmq[ i - 1 ][ j + ( 1 << ( i - 1 ) ) ] );
}
fin >> t;
for( int i = 0; i < t; i++ ) {
fin >> x >> y;
x = comptc[ x ];
y = comptc[ y ];
lca = low_com_anc( x, y );
if( x == lca )
rez = 0;
else {
rez = 1;
for( int step = lg[ comptc_num ]; step >= 0; --step )
if( anc[ step ][ x ] > lca ) {
rez += ( 1 << step );
x = anc[ step ][ x ];
}
}
fout << rez << '\n';
}
return 0;
}