Cod sursa(job #2314933)

Utilizator Radu_FilipescuFilipescu Radu Radu_Filipescu Data 9 ianuarie 2019 11:46:12
Problema Obiective Scor 35
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3 kb
#include <fstream>
#include <vector>
#include <deque>

using namespace std;

ifstream fin( "obiective.in" );
ofstream fout( "obiective.out" );

const int NMAX = 32005;
const int INF = 2000000000;

int N, M;

vector <int> Ad[NMAX];
vector <int> Ad_rev[NMAX];

vector <int> Ad2[NMAX];
vector <int> Ad2_rev[NMAX];

vector <int> T;

bool vis[NMAX];
int comp[NMAX];
int dist[NMAX];
bool in_q[NMAX];

int nr_comp;
int source, dest, ans;

int BFS()
{
   deque <int> Q;

   Q.push_back( comp[source] );
   in_q[ comp[source] ] = true;

   int target = comp[dest];
   int u, w;

   while( !Q.empty() )
   {
     u = Q.front();
     Q.pop_front();

     in_q[u] = false;

     //fout << u << ' ';

     for( int i = 0; i < Ad2[u].size(); ++i )
     {
       w = Ad2[u][i];

       //fout << w << ' ' << dist[w];

       if( dist[w] > dist[u] )
       {
         dist[w] = dist[u];

         if( !in_q[w] )
         Q.push_back(w);
       }
     }

     for( int i = 0; i < Ad2_rev[u].size(); ++i )
     {
       w = Ad2_rev[u][i];

       if( dist[w] > dist[u] + 1 )
       {
         dist[w] = dist[u] + 1;

         if( !in_q[w] )
         Q.push_back(w);
       }
     }
   }

   return dist[target];
}

void Read()
{
  fin >> N >> M;

  int x, y;

  for( int i = 1; i <= M; ++i )
  {
    fin >> x >> y;

    Ad[x].push_back(y);
    Ad_rev[y].push_back(x);
  }
}

void Topo( int nod )
{
  vis[nod] = true;

  int w;

  for( int i = 0; i < Ad[nod].size(); ++i )
  {
    w = Ad[nod][i];

    if( !vis[w] ) Topo( w );
  }

  T.push_back( nod );
}

void DFS( int nod, int nr_c )
{
  comp[nod] = nr_c;

  int w;

  for( int i = 0; i < Ad_rev[nod].size(); ++i )
  {
    w = Ad_rev[nod][i];

    if( comp[w] == 0 ) DFS( w, nr_c );
  }
}

void Init()
{
  for( int i = 1; i <= nr_comp; ++i )
    { dist[i] = INF;
      in_q[i] = 0;
    }

  dist[ comp[source]] = 0;
}

void Do()
{
  for( int i = 1; i <= N; ++i )
    if( !vis[i] ) Topo( i );

  for( int i = N - 1; i >= 0; --i )
    if( comp[ T[i] ] == 0 ) DFS( T[i], ++nr_comp );

  int w;

  //for( int i = 1; i <= N; ++i )
  //  fout << comp[i] << ' ';

  for( int i = 1; i <= N; ++i )
    for( int j = 0; j < Ad[i].size(); ++j )
    {
      w = Ad[i][j];

      //fout << w << ' ' << comp[w] << "   ";

      if( comp[i] != comp[w] )
      {
        Ad2[comp[i]].push_back( comp[w] );
        Ad2_rev[comp[w]].push_back( comp[i] );
      }
    }

  int nr_Q;

  fin >> nr_Q;

  /*for( int i = 1; i <= nr_comp; ++i )
  {
    for( int j = 0; j < Ad2[i].size(); ++j )
      fout << Ad2[i][j] << ' ';

    fout << '\n';
  }*/

  for( int i = 1; i <= nr_Q; ++i )
  {
    fin >> source >> dest;

    if( comp[source] == comp[dest] ) ans = 0;
    else
    {
      Init();

      ans = BFS();
    }
    //fout << '\n';

    fout << ans << '\n';
  }

  fin.close();
  fout.close();
}

int main()
{
    Read();
    Do();

    return 0;
}