Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //#pragma GCC optimize("Ofast")
- //#pragma GCC optimize ("unroll-loops")
- //#pragma GCC optimize ("fast-math")
- //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx2,tune=native")
- #define _CRT_SECURE_NO_WARNINGS
- //#include <bits/stdc++.h>
- #include <iostream>
- #include <algorithm>
- #include <string>
- #include <cmath>
- #include <vector>
- #include <map>
- #include <set>
- #include <list>
- #include <ctime>
- #include <stack>
- #include <queue>
- #include <iomanip>
- #include <cstdlib>
- #include <unordered_map>
- #include <unordered_set>
- #include <cstddef>
- #include <deque>
- #include <cstdio>
- #include <fstream>
- #include <random>
- #include <climits>
- #include <chrono>
- using namespace std;
- #define forn(i, j, k) for(int i = (int)(j); i < (int)(k); i++)
- #define forn1(i, j, k) for(int i = (int)(j); i <= (int)(k); i++)
- #define pb push_back
- #define mp make_pair
- #define f first
- #define s second
- #define all(x) begin(x), end(x)
- #define sz(a) ((int)((a).size()))
- #define endl '\n'
- const int INF = 1e9 + 1;
- const unsigned long long MOD = 1e9 + 7;
- typedef long long ll;
- typedef unsigned long long ull;
- typedef long double ld;
- //std::mt19937 rnd(chrono::system_clock::now().time_since_epoch().count());
- const int maxn = 100'007;
- vector<int> g[maxn];
- map<pair<int, int>, int> mapl;
- map<pair<int, int>, bool> is_bridge;
- vector<pair<int, int>> bridges;
- bool used[maxn];
- int timer, tin[maxn], fup[maxn];
- void dfs_bridge (int v, int p = -1) {
- used[v] = true;
- tin[v] = fup[v] = timer++;
- for (size_t i=0; i<g[v].size(); ++i) {
- int to = g[v][i];
- if (to == p) continue;
- if (used[to]) {
- fup[v] = min(fup[v], tin[to]);
- } else {
- dfs_bridge(to, v);
- fup[v] = min (fup[v], fup[to]);
- if (fup[to] > tin[v]) {
- is_bridge[make_pair(min(to, v), max(to, v))] = true;
- bridges.emplace_back(to, v);
- }
- }
- }
- }
- void find_bridges(int n) {
- timer = 0;
- for (int i=1; i<=n; ++i) {
- used[i] = false;
- }
- for (int i=1; i<=n; ++i) {
- if (!used[i]) {
- dfs_bridge(i);
- }
- }
- }
- vector<int> vertex_component;
- void dfs(int v, int cnt) {
- vertex_component[v] = cnt;
- used[v] = true;
- for (auto u : g[v]) {
- if (!used[u] && !is_bridge[make_pair(min(u, v), max(u, v))]) {
- dfs(u, cnt);
- }
- }
- }
- struct Graph {
- int n;
- int root;
- vector<vector<int>> g;
- vector<int> height;
- vector<vector<int>> bin_up;
- int logn;
- Graph (int n_, int root_, vector<pair<int, int>>& edges) : n(n_), root(root_), g(n_ + 1), height(n_ + 1),
- bin_up(int(log(n_)/log(2)) + 4, vector<int>(n_ + 1)),
- logn(int(log(n_)/log(2)) + 3) {
- for (auto [u, v] : edges) {
- u = vertex_component[u];
- v = vertex_component[v];
- g[u].push_back(v);
- g[v].push_back(u);
- }
- }
- void dfs(int v, int p = -1, int h = 1) {
- height[v] = h;
- bin_up[0][v] = (p == -1 ? v : p);
- for (auto u : g[v]) {
- if (u != p) {
- dfs(u, v, h + 1);
- }
- }
- }
- void start_lca() {
- dfs(root);
- for (int i = 1; i <= logn; ++i) {
- for (int j = 1; j <= n; ++j) {
- bin_up[i][j] = bin_up[i - 1][bin_up[i - 1][j]];
- }
- }
- }
- int lca(int x, int y) {
- if (x == y) {
- return x;
- }
- if (height[x] < height[y]) {
- swap(x, y);
- }
- int delta = height[x] - height[y];
- for (int pow = logn; pow >= 0; --pow) {
- if ((1 << pow) <= delta) {
- delta -= (1 << pow);
- x = bin_up[pow][x];
- }
- }
- if (x == y) {
- return x;
- }
- for (int pow = logn; pow >= 0; --pow) {
- if (bin_up[pow][x] != bin_up[pow][y]) {
- x = bin_up[pow][x];
- y = bin_up[pow][y];
- }
- }
- return bin_up[0][x];
- }
- int ans(int x, int y) {
- return height[lca(x, y)] - 1;
- }
- };
- void solve() {
- int n, m;
- cin >> n >> m;
- int f;
- cin >> f;
- forn(i, 0, m) {
- int u, v;
- cin >> u >> v;
- g[u].push_back(v);
- g[v].push_back(u);
- }
- find_bridges(n);
- vertex_component.resize(n + 1);
- fill(used, used + maxn - 1, false);
- int cnt = 0;
- for (int i = 1; i <= n; ++i) {
- if (!used[i]) {
- ++cnt;
- dfs(i, cnt);
- }
- }
- Graph tree(cnt, vertex_component[f], bridges);
- tree.start_lca();
- int k;
- cin >> k;
- while (k--) {
- int u, v;
- cin >> u >> v;
- u = vertex_component[u];
- v = vertex_component[v];
- cout << tree.ans(u, v) << endl;
- }
- }
- int32_t main() {
- ios_base::sync_with_stdio(false);
- cin.tie(NULL);
- cout.tie(NULL);
- cout.precision(30);
- int t;
- #ifdef LOCAL
- freopen("input.txt", "r", stdin);
- //freopen("output.txt", "w", stdout);
- cin >> t;
- #else
- t = 1;
- #endif
- while (t--) {
- solve();
- #ifdef LOCAL
- cout << "__________________________" << endl;
- #endif
- }
- #ifdef LOCAL
- cerr << endl << "finished in " << clock() * 1.0 / CLOCKS_PER_SEC << " sec" << endl;
- #endif
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement