Advertisement
playerr17

Untitled

May 7th, 2023
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.52 KB | None | 0 0
  1. //#pragma GCC optimize("Ofast")
  2. //#pragma GCC optimize ("unroll-loops")
  3. //#pragma GCC optimize ("fast-math")
  4. //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx2,tune=native")
  5. #define _CRT_SECURE_NO_WARNINGS
  6. //#include <bits/stdc++.h>
  7. #include <iostream>
  8. #include <algorithm>
  9. #include <string>
  10. #include <cmath>
  11. #include <vector>
  12. #include <map>
  13. #include <set>
  14. #include <list>
  15. #include <ctime>
  16. #include <stack>
  17. #include <queue>
  18. #include <iomanip>
  19. #include <cstdlib>
  20. #include <unordered_map>
  21. #include <unordered_set>
  22. #include <cstddef>
  23. #include <deque>
  24. #include <cstdio>
  25. #include <fstream>
  26. #include <random>
  27. #include <climits>
  28. #include <chrono>
  29.  
  30. using namespace std;
  31. #define forn(i, j, k) for(int i = (int)(j); i < (int)(k); i++)
  32. #define forn1(i, j, k) for(int i = (int)(j); i <= (int)(k); i++)
  33. #define pb push_back
  34. #define mp make_pair
  35. #define f first
  36. #define s second
  37. #define all(x) begin(x), end(x)
  38. #define sz(a) ((int)((a).size()))
  39. #define endl '\n'
  40. const int INF = 1e9 + 1;
  41. const unsigned long long MOD = 1e9 + 7;
  42. typedef long long ll;
  43. typedef unsigned long long ull;
  44. typedef long double ld;
  45. //std::mt19937 rnd(chrono::system_clock::now().time_since_epoch().count());
  46.  
  47. const int maxn = 100'007;
  48.  
  49. vector<int> g[maxn];
  50.  
  51. map<pair<int, int>, int> mapl;
  52.  
  53.  
  54. map<pair<int, int>, bool> is_bridge;
  55. vector<pair<int, int>> bridges;
  56.  
  57. bool used[maxn];
  58. int timer, tin[maxn], fup[maxn];
  59.  
  60. void dfs_bridge (int v, int p = -1) {
  61.    used[v] = true;
  62.    tin[v] = fup[v] = timer++;
  63.    for (size_t i=0; i<g[v].size(); ++i) {
  64.        int to = g[v][i];
  65.        if (to == p)  continue;
  66.        if (used[to]) {
  67.            fup[v] = min(fup[v], tin[to]);
  68.        } else {
  69.            dfs_bridge(to, v);
  70.            fup[v] = min (fup[v], fup[to]);
  71.            if (fup[to] > tin[v]) {
  72.                is_bridge[make_pair(min(to, v), max(to, v))] = true;
  73.                bridges.emplace_back(to, v);
  74.            }
  75.        }
  76.    }
  77. }
  78.  
  79. void find_bridges(int n) {
  80.    timer = 0;
  81.    for (int i=1; i<=n; ++i) {
  82.        used[i] = false;
  83.    }
  84.    for (int i=1; i<=n; ++i) {
  85.        if (!used[i]) {
  86.            dfs_bridge(i);
  87.        }
  88.    }
  89. }
  90.  
  91. vector<int> vertex_component;
  92.  
  93. void dfs(int v, int cnt) {
  94.    vertex_component[v] = cnt;
  95.    used[v] = true;
  96.    for (auto u : g[v]) {
  97.        if (!used[u] && !is_bridge[make_pair(min(u, v), max(u, v))]) {
  98.            dfs(u, cnt);
  99.        }
  100.    }
  101. }
  102.  
  103. struct Graph {
  104.    int n;
  105.    int root;
  106.    vector<vector<int>> g;
  107.    vector<int> height;
  108.    vector<vector<int>> bin_up;
  109.    int logn;
  110.  
  111.    Graph (int n_, int root_, vector<pair<int, int>>& edges) : n(n_), root(root_), g(n_ + 1), height(n_ + 1),
  112.                                                               bin_up(int(log(n_)/log(2)) + 4, vector<int>(n_ + 1)),
  113.                                                               logn(int(log(n_)/log(2)) + 3) {
  114.        for (auto [u, v] : edges) {
  115.            u = vertex_component[u];
  116.            v = vertex_component[v];
  117.            g[u].push_back(v);
  118.            g[v].push_back(u);
  119.        }
  120.    }
  121.  
  122.    void dfs(int v, int p = -1, int h = 1) {
  123.        height[v] = h;
  124.        bin_up[0][v] = (p == -1 ? v : p);
  125.        for (auto u : g[v]) {
  126.            if (u != p) {
  127.                dfs(u, v, h + 1);
  128.            }
  129.        }
  130.    }
  131.  
  132.    void start_lca() {
  133.        dfs(root);
  134.        for (int i = 1; i <= logn; ++i) {
  135.            for (int j = 1; j <= n; ++j) {
  136.                bin_up[i][j] = bin_up[i - 1][bin_up[i - 1][j]];
  137.            }
  138.        }
  139.    }
  140.  
  141.    int lca(int x, int y) {
  142.        if (x == y) {
  143.            return x;
  144.        }
  145.        if (height[x] < height[y]) {
  146.            swap(x, y);
  147.        }
  148.        int delta = height[x] - height[y];
  149.        for (int pow = logn; pow >= 0; --pow) {
  150.            if ((1 << pow) <= delta) {
  151.                delta -= (1 << pow);
  152.                x = bin_up[pow][x];
  153.            }
  154.        }
  155.        if (x == y) {
  156.            return x;
  157.        }
  158.        for (int pow = logn; pow >= 0; --pow) {
  159.            if (bin_up[pow][x] != bin_up[pow][y]) {
  160.                x = bin_up[pow][x];
  161.                y = bin_up[pow][y];
  162.            }
  163.        }
  164.        return bin_up[0][x];
  165.    }
  166.  
  167.    int ans(int x, int y) {
  168.        return height[lca(x, y)] - 1;
  169.    }
  170.  
  171. };
  172.  
  173. void solve() {
  174.    int n, m;
  175.    cin >> n >> m;
  176.    int f;
  177.    cin >> f;
  178.    forn(i, 0, m) {
  179.        int u, v;
  180.        cin >> u >> v;
  181.        g[u].push_back(v);
  182.        g[v].push_back(u);
  183.    }
  184.    find_bridges(n);
  185.    vertex_component.resize(n + 1);
  186.    fill(used, used + maxn - 1, false);
  187.    int cnt = 0;
  188.    for (int i = 1; i <= n; ++i) {
  189.        if (!used[i]) {
  190.            ++cnt;
  191.            dfs(i, cnt);
  192.        }
  193.    }
  194.    Graph tree(cnt, vertex_component[f], bridges);
  195.    tree.start_lca();
  196.  
  197.    int k;
  198.    cin >> k;
  199.  
  200.    while (k--) {
  201.        int u, v;
  202.        cin >> u >> v;
  203.        u = vertex_component[u];
  204.        v = vertex_component[v];
  205.        cout << tree.ans(u, v) << endl;
  206.    }
  207. }
  208.  
  209. int32_t main() {
  210.    ios_base::sync_with_stdio(false);
  211.    cin.tie(NULL);
  212.    cout.tie(NULL);
  213.    cout.precision(30);
  214.    int t;
  215. #ifdef LOCAL
  216.    freopen("input.txt", "r", stdin);
  217.    //freopen("output.txt", "w", stdout);
  218.    cin >> t;
  219. #else
  220.    t = 1;
  221. #endif
  222.    while (t--) {
  223.        solve();
  224. #ifdef LOCAL
  225.        cout << "__________________________" << endl;
  226. #endif
  227.    }
  228. #ifdef LOCAL
  229.    cerr << endl << "finished in " << clock() * 1.0 / CLOCKS_PER_SEC << " sec" << endl;
  230. #endif
  231.    return 0;
  232. }
  233.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement