BotByte

Centroid Decomposition.cpp

May 3rd, 2018
237
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.61 KB | None | 0 0
  1. /*
  2.     Author: M. A. Rafsan Mazumder
  3.     Algorithm : Centroid Decomposition
  4.     Problem : Codeforces 342E - Xenia and Tree
  5. */
  6.  
  7. /*
  8.     Xenia the programmer has a tree consisting of n nodes. We will consider the tree nodes indexed from 1 to n.
  9.     We will also consider the first node to be initially painted red, and the other nodes — to be painted blue.
  10.     The distance between two tree nodes v and u is the number of edges in the shortest path between v and u.
  11.     Xenia needs to learn how to quickly execute queries of two types:
  12.  
  13.     1. paint a specified blue node in red;
  14.     2. calculate which red node is the closest to the given one and print the shortest distance to the closest red node.
  15. */
  16.  
  17. #include <bits/stdc++.h>
  18.  
  19. using namespace std;
  20.  
  21. #define MAX 100005
  22. #define MAX_LOG 20
  23. #define INF 1000000
  24. set<int> S[MAX];
  25. int centree[MAX], comp = 0, subSize[MAX];
  26. int level[MAX], par[MAX][MAX_LOG], ans[MAX];
  27.  
  28. void dfs(int u, int pre, int depth)
  29. {
  30.     level[u] = depth;
  31.     par[u][0] = pre;
  32.  
  33.     set<int> ::iterator it = S[u].begin();
  34.     for(; it!=S[u].end(); it++){
  35.         int v = *it;
  36.         if(v == pre) continue;
  37.         dfs(v, u, depth+1);
  38.     }
  39. }
  40.  
  41. void visit(int u, int par)
  42. {
  43.     ++comp;
  44.     subSize[u] = 1;
  45.     set<int> ::iterator it = S[u].begin();
  46.     for(; it!= S[u].end(); it++){
  47.         int v = *it;
  48.         if(v == par) continue;
  49.         visit(v, u);
  50.         subSize[u] += subSize[v];
  51.     }
  52. }
  53.  
  54. int find_centroid(int u, int par)
  55. {
  56.     set<int> ::iterator it = S[u].begin();
  57.     for(; it!=S[u].end(); it++){
  58.         int v = *it;
  59.         if(v == par) continue;
  60.         if(subSize[v] > comp/2) return find_centroid(v, u);
  61.     }
  62.     return u;
  63. }
  64.  
  65. void decompose(int u, int par)
  66. {
  67.     comp = 0;
  68.     visit(u, u);
  69.     int centroid = find_centroid(u, u);
  70.     centree[centroid] = par;
  71.  
  72.     set<int> ::iterator it = S[centroid].begin();
  73.     for(; it!=S[centroid].end(); it++){
  74.         int v = *it;
  75.         S[v].erase(centroid);
  76.         decompose(v, centroid);
  77.     }
  78.     S[centroid].clear();
  79. }
  80.  
  81. int LCA(int u, int v)
  82. {
  83.     if(level[u] < level[v]) swap(u, v);
  84.     int diff = level[u]-level[v];
  85.     for(int i=0; i<MAX_LOG; i++){
  86.         if((1<<i) & diff) u = par[u][i];
  87.     }
  88.     if(u == v) return u;
  89.     for(int i=MAX_LOG-1; i>=0; i--){
  90.         if(par[u][i] != par[v][i]){
  91.             u = par[u][i];
  92.             v = par[v][i];
  93.         }
  94.     }
  95.     return par[u][0];
  96. }
  97.  
  98. int dist(int u, int v)
  99. {
  100.     int lca = LCA(u, v);
  101.     return level[u]+level[v]-2*level[lca];
  102. }
  103.  
  104. void update(int node)
  105. {
  106.     int x = node;
  107.     while(x != -1){
  108.         ans[x] = min(ans[x], dist(x, node));
  109.         x = centree[x];
  110.     }
  111. }
  112.  
  113. int query(int node)
  114. {
  115.     int mins = INF;
  116.     int x = node;
  117.     while(x != -1){
  118.         mins = min(mins, ans[x] + dist(x, node));
  119.         x = centree[x];
  120.     }
  121.     return mins;
  122. }
  123.  
  124. int main()
  125. {
  126.     //freopen("in.txt", "r", stdin);
  127.     int n, m;
  128.     scanf("%d %d", &n, &m);
  129.     for(int i=0; i<n-1; i++){
  130.         int u, v;
  131.         scanf("%d %d", &u, &v);
  132.         S[u].insert(v);
  133.         S[v].insert(u);
  134.     }
  135.     memset(par, -1, sizeof par);
  136.     dfs(1, -1, 0);
  137.     for(int j=1; j<MAX_LOG; j++){
  138.         for(int i=1; i<=n; i++) par[i][j] = par[par[i][j-1]][j-1];
  139.     }
  140.     decompose(1, -1);
  141.     for(int i=0; i<MAX; i++) ans[i] = INF;
  142.     update(1);
  143.     for(int i=0; i<m; i++){
  144.         int type, node;
  145.         scanf("%d %d", &type, &node);
  146.         if(type == 1) update(node);
  147.         else printf("%d\n", query(node));
  148.     }
  149. }
  150.  
  151. /*
  152.     5 4
  153.     1 2
  154.     2 3
  155.     2 4
  156.     4 5
  157.     2 1
  158.     2 5
  159.     1 2
  160.     2 5
  161.  
  162.     0
  163.     3
  164.     2
  165. */
Advertisement
Add Comment
Please, Sign In to add comment