Cod sursa(job #2730477)

Utilizator PetyAlexandru Peticaru Pety Data 26 martie 2021 13:27:58
Problema Obiective Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.16 kb
#include <bits/stdc++.h>
 
using namespace std;
 
ifstream fin ("obiective .in");
ofstream fout ("obiective.out");
 
bool viz[32002];
int n, m, x, y, nr, c[32002], grad[32002];
 
vector<int>v1[32002];
vector<int>v2[32002];
vector<int>ctc[32002];
stack<int>st;
 
void dfs (int x) {
  viz[x] = 1;
  for (int i = 0; i < v1[x].size(); i++) {
    if (!viz[v1[x][i]])
      dfs(v1[x][i]);
  }
  st.push(x);
}
 
void dfs2 (int x) {
  viz[x] = 1;
  for (int i = 0; i < v2[x].size(); i++) {
    if (!viz[v2[x][i]])
      dfs2(v2[x][i]);
  }
  c[x] = nr;
}

int dp[17][32002], lvl[32002], dp2[17][32002];

void dfslol (int x, int par) {
  dp2[0][x] = par;
  dp[0][x] = par;
  lvl[x] = lvl[par] + 1;
  viz[x] = 1;
  for (auto it : ctc[x]) {
    if (!viz[it]) {
      dfslol(it, x);
    }
    else {
      if (lvl[dp2[0][it]] > lvl[x])
        dp2[0][it] = x;
    }
  }
}

void preamultdfs (int x, int par) {
  viz[x]  = 1;
  for (auto it : ctc[x]) {
    if (viz[it] == 0) {
      preamultdfs(it, x);
      if (lvl[dp2[0][x]] > lvl[dp2[0][it]])
        dp2[0][x] = dp2[0][it];
    }
  }
}

set<pair<int, int> > s;

int lca (long long u, long long v) {
  if (lvl[u] > lvl[v])
    swap(u, v);
  long long meh = lvl[v] - lvl[u];
  assert(meh >= 0);
  for (long long i = 16; i >= 0; i--) 
    if (meh & (1 << i)) {
      v = dp[i][v];
    }
  if (u == v) {
    return v;
  }
  for (long long i = 16; i >= 0; i--) {
    if (dp[i][u] != dp[i][v]) {
      u = dp[i][u];
      v = dp[i][v];
    }
  }
  if (v == 0) {
    cout << u << " " << v << "\n";
    exit(0);
  }
  return dp[0][v];
}
 
int main()
{
  fin >> n >> m;
  for (int i = 1; i <= m; i++) {
    fin >> x >> y;
    v1[x].push_back(y);
    v2[y].push_back(x);
  }
  for (int i = 1; i <= n; i++) {
    if (viz[i] == 0)
      dfs(i);
  }
  memset(viz, 0, sizeof(viz));
  while (!st.empty()) {
    if (viz[st.top()] == 0) {
      nr++;
      dfs2(st.top());
    }
    st.pop();
  }
  for (int i = 1; i <= n; i++) 
    for (auto it : v1[i])
      if (c[it] != c[i] && s.find({c[i], c[it]}) == s.end()) {
        s.insert({c[i], c[it]});
        s.insert({c[it], c[i]});
        ctc[c[i]].push_back({c[it]});
        grad[c[it]]++;
      }
  for (int i = 1; i <= nr; i++) {
    sort(ctc[i].begin(), ctc[i].end());
  }
  int root = 0;
  for (int i = 1; i <= nr; i++)
    if (grad[i] == 0)
      root = i;
  memset(viz, false, sizeof(viz));
  dfslol(root, 0);
  memset(viz, false, sizeof(viz));
  preamultdfs(root, 0);
  for (int i = 1; (1 << i) <= nr; i++)
    for (int j = 1; j <= n; j++) {
      dp[i][j] = dp[i - 1][dp[i - 1][j]];
      dp2[i][j] = dp2[i - 1][dp2[i - 1][j]];
    }
  //cout << dp[1][c[11]] << " " << c[8] << "\n";
  int t;  
  fin >> t;
  while (t--) {
    fin >> x >> y;
    //cout << x << " " << y << "\n";
    x = c[x];
    y = c[y];
    if (x == y) {
      fout << "0\n";
      continue;
    }
    else {
      //cout << lvl[x] << " " << lvl[y] << "\n";
      int l = lca(x, y);
      if (x == l) {
        fout << "0\n";
        continue;
      }
      int ans = 0;
      for (int i = 16; i >= 0; i--)
        if (dp2[i][x] != 0 && lvl[dp2[i][x]] > lvl[l]) {
          x = dp2[i][x];
          ans += (1 << i);
        }
      fout << ans + 1 << "\n";
    }
  }
  return 0;
}