Friday, April 24, 2020

[CS Academy] Root Change

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : Root Change
Source            : CS Academy 
Category          : Graph Theory, Tree
Algorithm         : Re-Rooting Technique
Verdict           : Accepted

  1. #include "bits/stdc++.h"  
  2.   
  3. using namespace std;  
  4.   
  5. #define ll           long long int   
  6. #define endl         '\n'  
  7.   
  8. static const int maxn = 2e5 + 5;  
  9. static const int logn = 19;  
  10.   
  11. vector < vector <int> > graph;  
  12. int depth[maxn];  
  13. int father[maxn][logn];  
  14.   
  15. void dfs(int u, int p = -1) {  
  16.     for (int i = 1; i < logn; i++) {  
  17.         father[u][i] = father[ father[u][i - 1] ][i - 1];  
  18.     }  
  19.     for (int v : graph[u]) {  
  20.         if (v == p) continue;  
  21.         depth[v] = depth[u] + 1;  
  22.         father[v][0] = u;  
  23.         dfs(v, u);  
  24.     }  
  25. }  
  26.   
  27. int find_lca(int u, int v) {  
  28.     if (depth[u] < depth[v]) {  
  29.         swap(u, v);  
  30.     }  
  31.     for (int i = logn - 1; i >= 0; i--) {  
  32.         if (depth[ father[u][i] ] >= depth[v]) {  
  33.             u = father[u][i];  
  34.         }  
  35.     }  
  36.     if (u == v) {  
  37.         return u;  
  38.     }  
  39.     for (int i = logn - 1; i >= 0; i--) {  
  40.         if (father[u][i] != father[v][i]) {  
  41.             u = father[u][i];  
  42.             v = father[v][i];  
  43.         }  
  44.     }  
  45.     return father[u][0];  
  46. }  
  47.   
  48. int dist(int u, int v) {  
  49.     int lca = find_lca(u, v);  
  50.     return depth[u] + depth[v] - 2 * depth[lca];  
  51. }  
  52.   
  53. #define pii           pair <int, int>  
  54. #define mk            make_pair  
  55. #define ff            first  
  56. #define ss            second  
  57.   
  58. pii dp[maxn];  
  59.   
  60. void solve(int u, int p = -1) {  
  61.     dp[u] = mk(0, u);  
  62.     for (int v : graph[u]) {  
  63.         if (v == p) continue;  
  64.         solve(v, u);  
  65.         if (1 + dp[v].ff > dp[u].ff) {  
  66.             dp[u].ff = 1 + dp[v].ff;  
  67.             dp[u].ss = dp[v].ss;  
  68.         }  
  69.     }  
  70.     int cnt = 0;  
  71.     for (int v : graph[u]) {  
  72.         if (v == p) continue;  
  73.         if (1 + dp[v].ff == dp[u].ff) {  
  74.             cnt++;  
  75.         }  
  76.     }  
  77.     if (cnt > 1) {  
  78.         dp[u].ss = u;  
  79.     }  
  80. }  
  81.   
  82. int n;  
  83. int ans[maxn];  
  84. pii dp2[maxn];  
  85.   
  86. void solution(int u, int p = 0) {  
  87.     ans[u] = n - 1 - dist(u, dp[u].ss);  
  88.     set <pii> st;  
  89.     int maxi = 0;  
  90.     if (p) {  
  91.         maxi = dp[p].ff;  
  92.         st.insert(dp[p]);  
  93.     }  
  94.     for (int v : graph[u]) {  
  95.         if (v == p) continue;  
  96.         if (dp[v].ff > maxi) {  
  97.             maxi = dp[v].ff;  
  98.         }   
  99.         st.insert(dp[v]);  
  100.     }  
  101.     for (int v : graph[u]) {  
  102.         if (v == p) continue;  
  103.         pii tempu = dp[u];  
  104.         pii tempv = dp[v];  
  105.         st.erase(dp[v]);  
  106.         if (st.size() == 0) {  
  107.             dp[u].ff = 0;  
  108.             dp[u].ss = u;  
  109.         } else {  
  110.             pii beg = *st.rbegin();  
  111.             dp[u].ff = 1 + beg.ff;  
  112.             dp[u].ss = beg.ss;  
  113.             st.erase(beg);  
  114.             if (st.size()) {  
  115.                 pii chk = *st.rbegin();  
  116.                 if (chk.ff == beg.ff) {  
  117.                     dp[u].ss = u;  
  118.                 }  
  119.             }  
  120.             st.insert(beg);  
  121.         }  
  122.         if (1 + dp[u].ff > dp[v].ff) {  
  123.             dp[v].ff = 1 + dp[u].ff;  
  124.             dp[v].ss = dp[u].ss;  
  125.         } else if (1 + dp[u].ff == dp[v].ff) {  
  126.             dp[v].ss = v;  
  127.         }  
  128.         st.insert(tempv);  
  129.         solution(v, u);  
  130.         dp[u] = tempu;  
  131.         dp[v] = tempv;  
  132.     }  
  133. }  
  134.   
  135. signed main()  
  136. {  
  137.     ios_base::sync_with_stdio(false);  
  138.     cin.tie(nullptr);  
  139.       
  140.     cin >> n;  
  141.     graph.resize(n + 1);  
  142.     for (int e = 1; e < n; e++) {  
  143.         int u, v;  
  144.         cin >> u >> v;  
  145.         graph[u].push_back(v);  
  146.         graph[v].push_back(u);  
  147.     }  
  148.     int root = 1;  
  149.     for (int i = 1; i <= n; i++) {  
  150.         if (graph[i].size() == 1) {  
  151.             root = i;  
  152.             break;  
  153.         }   
  154.     }  
  155.     depth[root] = 1;  
  156.     dfs(root);  
  157.     solve(root);  
  158.     solution(root);  
  159.     for (int i = 1; i <= n; i++) cout << ans[i] << endl;  
  160. }