Cod sursa(job #2110326)

Utilizator lflorin29Florin Laiu lflorin29 Data 20 ianuarie 2018 15:49:42
Problema Obiective Scor 5
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.76 kb
#include <bits/stdc++.h>
#define int long long
using namespace std;
#define For(i, a, b) for(int i = (int)(a); i <= (int)(b); ++i)
#define pb push_back
const int N = 32002;
int n, m, t, ctcount, id[N], anc[17][N], low[17][N], dep[N];
vector<int>G[N], T[N];
vector<int>Forw[N], Back[N];
bool u[N];
vector<int>lst;
void dfs1(int x) {
   u[x] = 1;
   for(int y : G[x])if(!u[y])dfs1(y);
   lst.push_back(x);
}
void dfs2(int x) {

   id[x] = ctcount;
   u[x] = 1;
   for(int y : T[x]) if(!u[y]) dfs2(y);
}
void change(int x, int nw) {
   if(dep[nw] < dep[low[0][x]]) {
      low[0][x] = nw;
   }
}
void TDfs(int x) {
   for(int y : Forw[x]) {
      dep[y] = dep[x] + 1;
      low[0][y] = x;
      TDfs(y);
      change (x, low[0][y]);
   }
   for(int y : Back[x]) {
      change (x, y);
   }
}
void scc() {
   For(i, 1, n) if(!u[i]) dfs1(i);
   fill(u + 1, u + n + 1, 0);
   for(int i = lst.size() - 1; i >= 0; --i) {
      if(!u[lst[i]]) {
         ++ctcount;
         dfs2(lst[i]);
      }
   }
   For(i, 1, ctcount) anc[0][i] = n + 1;
   anc[0][1] = 0;
   For(x, 1, n) {
      for(int y : G[x]) {
         if(id[x] == id[y])
            continue;
         anc[0][id[y]] = min(anc[0][id[y]], id[x]);
      }
   }
   For(x, 1, n) {
      for(int y : G[x]) {
         int i = id[x], j = id[y];
         if(i == j) continue;
         if(i == anc[0][j]) {
            Forw[i].push_back(j);
         } else Back[i].push_back(j);
      }
   }
   For(x, 1, ctcount) low[0][x] = anc[0][x];
   low[0][1] = 0;
   TDfs(1);
   for(int i = 1; (1 << i) <= ctcount; ++i)
      for(int j = 1; j <= ctcount; ++j) {
         low[i][j] = low[i - 1][low[i - 1][j]];
         anc[i][j] = anc[i - 1][anc[i - 1][j]];
      }
}
int LCA(int x, int y) {
   if(dep[x] < dep[y])swap(x, y);
   for(int i = 16; i >= 0; --i)if(dep[x] - (1 << i) >= dep[y])
         x = anc[i][x];
   if(x == y)return x;
   for(int i = 16; i >= 0; --i)
      if(anc[i][x] != anc[i][y] && anc[i][x] && anc[i][y]) {
         x = anc[i][x];
         y = anc[i][y];
      }
   return anc[0][x];
}
int solve (int x, int y) {
   int u = LCA(x, y);
   if(u == x) return 0;
   int sol = 0;
   for(int i = 16; i >= 0; --i) {
      int who = low[i][x];
      if(dep[who] > dep[u]) {
         sol += (1 << i);
         x = who;
      }
   }
   return 1 + sol;
}
int32_t main() {
   ifstream cin("obiective.in");
   ofstream cout("obiective.out");
   cin >> n >> m;
   For(i, 1, m) {
      int x, y;
      cin >> x >> y;
      G[x].pb(y);
      T[y].pb(x);
   }
   scc();
   cin >> t;
   For(i, 1, t) {
      int x, y;
      cin >> x >> y;
      x = id[x];
      y = id[y];
      if(x == y) {
         cout << 0 << '\n';
      } else cout << solve(x, y) << '\n';
   }
}