niyaznigmatullin

Centroid decomposition

Jul 6th, 2015
399
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.62 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. struct edge {
  6.     int from;
  7.     int to;
  8.     int w;
  9. };
  10.  
  11. struct node {
  12.     int v;
  13.     int d;
  14. };
  15.  
  16. int const N = 333333;
  17.  
  18. vector<edge> edges[N];
  19. vector<node> sv[N];
  20. int sz[N], banned[N];
  21. multiset<int> best[N];
  22. int painted[N];
  23.  
  24. void dfs(int v, int p) {
  25.     sz[v] = 1;
  26.     for (edge & e : edges[v]) {
  27.         if (e.to == p || banned[e.to]) continue;
  28.         dfs(e.to, v);
  29.         sz[v] += sz[e.to];
  30.     }
  31. }
  32.  
  33. void dfs2(int v, int p, int centroid, int d) {
  34.     sv[v].push_back({centroid, d});
  35.     for (edge & e : edges[v]) {
  36.         if (e.to == p || banned[e.to]) continue;
  37.         dfs2(e.to, v, centroid, d + e.w);
  38.     }
  39. }
  40.  
  41. void go(int v) {
  42.     dfs(v, -1);
  43.     int all = sz[v];
  44.     {
  45.         int pv = -1;
  46.         while (true) {
  47.             bool changed = false;
  48.             for (edge & e : edges[v]) {
  49.                 if (e.to == pv || banned[e.to]) continue;
  50.                 if (sz[e.to] * 2 > all) {
  51.                     pv = v;
  52.                     v = e.to;
  53.                     changed = true;
  54.                     break;
  55.                 }
  56.             }
  57.             if (!changed) break;
  58.         }
  59.     }
  60.     dfs2(v, -1, v, 0);
  61.     banned[v] = true;
  62.     for (edge & e : edges[v]) {
  63.         if (!banned[e.to]) go(e.to);
  64.     }
  65. }
  66.  
  67. int const INF = 1 << 29;
  68.  
  69. int main() {
  70.     freopen("treeeg.in", "r", stdin);
  71.     freopen("treeeg.out", "w", stdout);
  72.     int n;
  73.     scanf("%d", &n);
  74.     for (int i = 0; i + 1 < n; i++) {
  75.         int v, u, l;
  76.         scanf("%d%d%d", &v, &u, &l);
  77.         --v;
  78.         --u;
  79.         edges[v].push_back({v, u, l});
  80.         edges[u].push_back({u, v, l});
  81.     }
  82.     go(0);
  83.     int q;
  84.     scanf("%d", &q);
  85.     painted[0] = true;
  86.     for (node & e : sv[0])
  87.         best[e.v].insert(e.d);
  88.     for (int i = 0; i < q; i++) {
  89.         int c = getchar();
  90.         while (c <= 32) c = getchar();
  91.         int v;
  92.         scanf("%d", &v);
  93.         --v;
  94.         if (c == '?') {
  95.             int ans = INF;
  96.             for (node & e : sv[v]) {
  97.                 if (!best[e.v].empty())
  98.                     ans = min(ans, e.d + *best[e.v].begin());
  99.             }
  100.             printf("%d\n", ans);
  101.         } else if (c == '+') {
  102.             if (!painted[v]) {
  103.               for (node & e : sv[v]) {
  104.                   best[e.v].insert(e.d);
  105.               }
  106.               painted[v] = true;
  107.             }
  108.         } else {
  109.             if (painted[v]) {
  110.               for (node & e : sv[v]) {
  111.                   best[e.v].erase(best[e.v].find(e.d));
  112.               }
  113.               painted[v] = false;
  114.             }
  115.         }
  116.     }
  117. }
Advertisement
Add Comment
Please, Sign In to add comment