Pagini recente » Cod sursa (job #1112874) | Cod sursa (job #1106095) | Cod sursa (job #2401914) | Cod sursa (job #217949) | Cod sursa (job #3121344)
#include <fstream>
#include <vector>
#include <stack>
#include <set>
using namespace std;
ifstream fin( "obiective.in" );
ofstream fout( "obiective.out" );
const int MAX = 32e3 + 1;
const int MAXLOG = 17;
const int INF = 2e9;
stack<int> srt;
set<int> dag[ MAX ];
vector<int> g[ MAX ];
vector<int> gt[ MAX ];
int rmq[ MAXLOG + 1 ][ 2 * MAX ];
int anc[ MAXLOG + 1 ][ MAX ];
int comptc[ MAX ];
int lg[ 2 * MAX ];
bool seen[ MAX ];
int prim[ MAX ];
int comptc_num;
int euler_num;
void dfs( int node ) {
seen[ node ] = true;
for( auto it : g[ node ] )
if( seen[ it ] == false )
dfs( it );
srt.push( node );
}
void dfsR( int node ) {
seen[ node ] = false;
comptc[ node ] = comptc_num;
for( auto it : gt[ node ] )
if( seen[ it ] )
dfsR( it );
}
void euler( int node ) {
seen[ node ] = true;
prim[ node ] = ++euler_num;
rmq[ 0 ][ euler_num ] = node;
for( auto it : dag[ node ] )
if( seen[ it ] == 0 ) {
euler( it );
rmq[ 0 ][ ++euler_num ] = node;
anc[ 0 ][ node ] = min( anc[ 0 ][ node ], anc[ 0 ][ it ] );
}
}
int LCA( 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()
{
ios_base::sync_with_stdio(false);
fin.tie(NULL);
int n, m, x, y, t, lca, rez;
for( int i = 2; i <= 2 * MAX; ++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 )
dfs( i );
while( srt.empty() == 0 ) {
if( seen[ srt.top() ] ) {
++comptc_num;
dfsR( 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( 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 = LCA( 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;
}