Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define PIHAYEM_S_NOGI 1
- #include<bits/stdc++.h>
- using namespace std;
- #ifdef PIHAYEM_S_NOGI
- #pragma GCC optimize("Ofast")
- #pragma GCC optimize("no-stack-protector")
- #pragma GCC optimize("unroll-loops")
- #pragma GCC target("sse,sse2,sse3,ssse3,popcnt,abm,mmx,tune=native")
- #pragma GCC optimize("fast-math")
- #include <ext/pb_ds/assoc_container.hpp>
- using namespace __gnu_pbds;
- #define unordered_map gp_hash_table
- #endif
- #define dbg(x) cout << __func__ << ':' << __LINE__ << ' ' << #x << " = " << x << endl
- #define endl '\n'
- // #define int long long
- #define double long double
- #define sqr(x) (x) * (x)
- #define eb emplace_back
- #define pb push_back
- #define f first
- #define s second
- #define all(x) x.begin(), x.end()
- vector<vector<int> > g;
- vector<vector<int> > c;
- vector<int> tin, tout;
- vector<int> fup;
- vector<bool> so;
- vector<int> clr;
- int col = 1;
- int timer = 0;
- void dfs(int v, int p = -1){
- tin[v] = timer++;
- fup[v] = tin[v];
- int subtrees = 0;
- for(int i = 0; i < g[v].size(); i++){
- int to = g[v][i];
- int cc = c[v][i];
- if(to == p) continue;
- if(tin[to] == -1){
- dfs(to, v);
- fup[v] = min(fup[v], fup[to]);
- if (fup[to] > tin[v]){
- so[cc] = 1;
- }
- subtrees++;
- } else{
- fup[v] = min(fup[v], tin[to]);
- }
- }
- tout[v] = timer++;
- }
- void paint(int v){
- clr[v] = col;
- for(int i = 0; i < g[v].size(); i++){
- int to = g[v][i];
- int cc = c[v][i];
- if(so[cc]) continue;
- if(!clr[to]) paint(to);
- }
- }
- vector<set<int> > t;
- vector<vector<int> > up;
- vector<int> h;
- void ddfs(int v, int p = -1, int hh = 0){
- h[v] = hh;
- if(p == -1) up[v][0] = v;
- else up[v][0] = p;
- for(int i = 1; i < 19; i++){
- up[v][i] = up[up[v][i - 1]][i - 1];
- }
- for(int to: t[v]){
- if(to == p) continue;
- ddfs(to, v, hh + 1);
- }
- }
- void goUp(int &u, int &v){
- int hc = min(h[u], h[v]);
- for(int i = 18; i >= 0; i--){
- if(h[up[u][i]] >= hc) u = up[u][i];
- if(h[up[v][i]] >= hc) v = up[v][i];
- }
- }
- int lca(int u, int v){
- goUp(u, v);
- if(u == v) return u;
- for(int i = 18; i >= 0; i--){
- if(up[u][i] == up[v][i]) continue;
- u = up[u][i];
- v = up[v][i];
- }
- return up[v][0];
- }
- signed main() {
- srand(time(0));
- #ifdef DEBUG
- freopen("input.txt", "r", stdin);
- #else
- // freopen("convex.in", "r", stdin);
- // freopen("convex.out", "w", stdout);
- #endif
- ios_base::sync_with_stdio(false);
- cin.tie(0);
- cout.tie(0);
- int n, m;
- cin >> n >> m;
- g.resize(n);
- c.resize(n);
- tin.resize(n, -1);
- tout.resize(n);
- fup.resize(n);
- so.resize(m, 0);
- clr.resize(n, 0);
- int f;
- cin >> f;
- f--;
- vector<pair<int, int> > e;
- for(int i = 0; i < m; i++){
- int u, v;
- cin >> u >> v;
- u--, v--;
- e.push_back({u, v});
- g[u].push_back(v);
- c[v].push_back(i);
- c[u].push_back(i);
- g[v].push_back(u);
- }
- for(int v = 0; v < n; v++){
- if(tin[v] == -1) dfs(v);
- }
- // for(int i = 0; i < m; i++) if(so[i]) cout << i + 1 << endl;
- for(int v = 0; v < n; v++){
- if(clr[v] == 0){
- paint(v);
- col++;
- }
- }
- t.resize(col);
- up.resize(col, vector<int>(19, 0));
- h.resize(col);
- for(auto a: e){
- int u = a.first, v = a.second;
- if(clr[v] == clr[u]) continue;
- t[clr[v]].insert(clr[u]);
- t[clr[u]].insert(clr[v]);
- }
- ddfs(clr[f]);
- int k;
- cin >> k;
- for(int i = 0; i < k; i++){
- int u, v;
- cin >> u >> v;
- u--, v--;
- u = clr[u];
- v = clr[v];
- cout << h[lca(u, v)] << endl;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement