Cod sursa(job #2104642)

Utilizator lflorin29Florin Laiu lflorin29 Data 11 ianuarie 2018 23:51:44
Problema Obiective Scor 5
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.08 kb
#include <bits/stdc++.h>

using namespace std;

int const N = 32000 + 2;
int n, m, t;
vector<int>G[N], T[N];
int wscc[N], sccind;
bool vis[N];
vector<int>order;
vector<int>sccG[N];
int prv[N];
vector<int>TreeG[N];
int anc[17][N], dep[N];
void dfs(int x) {
   vis[x] = 1;
   for(int y : G[x]) if(!vis[y]) dfs(y);
   order.push_back(x);
}
void dfs2(int x) {

   vis[x] = 1;
   wscc[x] = sccind;
   for(int y : T[x])
      if(!vis[y]) dfs2(y);
}
int lca(int x, int y) {
   if(dep[x] < dep[y]) swap(x, y);
   for(int i = 15; i >= 0; --i) if(dep[x] - (1 << i) >= dep[y]) x = anc[i][x];
   if(x == y) return x;
   for(int i = 15; i >= 0; --i) if(anc[i][x] > 0 && anc[i][y] > 0 && anc[i][x] != anc[i][y]) x = anc[i][x], y = anc[i][y];
   return anc[0][x];
}
int qry(int x, int y) {
   int up = lca(x, y);
   return dep[x] - dep[up];
}
void tdfs(int x) {
   for(int y : TreeG[x]) {
      dep[y] = dep[x] + 1;
      tdfs(y);
   }
}
void findsccs() {
   for(int i = 1; i <= n; ++i) if(!vis[i]) dfs(i);
   fill(vis + 1, vis + n + 1, 0);
   for(int i = order.size() - 1; i >= 0; --i) {
      if(!vis[order[i]]) {
         ++sccind;
         dfs2(order[i]);
      }
   }
   for(int i = 1; i <= sccind; ++i)
      anc[0][i] = n + 1;
   for(int i = 1; i <= n; ++i) {
      for(int j : G[i]) {
         if(wscc[i] != wscc[j]) {
            int ci = wscc[i], cj = wscc[j];
            anc[0][cj] = min(anc[0][cj], ci);
         }
      }
   }
   for(int i = 1; i <= n; ++i)TreeG[anc[0][i]].push_back(i);
   anc[0][1] = 0;
   for(int p = 1; (1 << p) <= sccind; ++p)
      for(int i = 1; i <= sccind; ++i)
         anc[p][i] = anc[p - 1][anc[p - 1][i]];
   tdfs(1);
}


int main() {
   ifstream cin("obiective.in");
   ofstream cout("obiective.out");
   cin >> n >> m;
   for(int i = 1; i <= m; ++i) {
      int x, y;
      cin >> x >> y;
      G[x].push_back(y);
      T[y].push_back(x);
   }
   cin >> t;
   findsccs();
   while(t--) {
      int x, y;
      cin >> x >> y;
      x = wscc[x];
      y = wscc[y];
      cout << qry(x, y) << '\n';
   }

}