CP-templates

This documentation is automatically generated by online-judge-tools/verification-helper

View the Project on GitHub Misuki743/CP-templates

:heavy_check_mark: tree/centroid_tree.cpp

Verified with

Code

auto centroid_tree(vvi &g) {
  int n = ssize(g);
  vvi tr(n);
  vi sz(n);
  vc<bool> block(n, false);

  auto calc = [&](int v, int p, auto &self) -> void {
    sz[v] = 1;
    for(int x : g[v]) {
      if (x == p or block[x]) continue;
      self(x, v, self);
      sz[v] += sz[x];
    }
  };

  auto dfs = [&](int v, auto &self) -> int {
    calc(v, -1, calc);

    int c = v, p = -1;
    bool move;
    do {
      move = false;
      for(int x : g[c]) {
        if (x == p or block[x] or 2 * sz[x] <= sz[v]) continue;
        move = true, p = c, c = x;
        break;
      }
    } while(move);

    block[c] = true;
    for(int x : g[c]) {
      if (block[x]) continue;
      x = self(x, self);
      tr[c].emplace_back(x);
      tr[x].emplace_back(c);
    }

    return c;
  };

  int root = dfs(0, dfs);

  return pair(tr, root);
}
#line 1 "tree/centroid_tree.cpp"
auto centroid_tree(vvi &g) {
  int n = ssize(g);
  vvi tr(n);
  vi sz(n);
  vc<bool> block(n, false);

  auto calc = [&](int v, int p, auto &self) -> void {
    sz[v] = 1;
    for(int x : g[v]) {
      if (x == p or block[x]) continue;
      self(x, v, self);
      sz[v] += sz[x];
    }
  };

  auto dfs = [&](int v, auto &self) -> int {
    calc(v, -1, calc);

    int c = v, p = -1;
    bool move;
    do {
      move = false;
      for(int x : g[c]) {
        if (x == p or block[x] or 2 * sz[x] <= sz[v]) continue;
        move = true, p = c, c = x;
        break;
      }
    } while(move);

    block[c] = true;
    for(int x : g[c]) {
      if (block[x]) continue;
      x = self(x, self);
      tr[c].emplace_back(x);
      tr[x].emplace_back(c);
    }

    return c;
  };

  int root = dfs(0, dfs);

  return pair(tr, root);
}
Back to top page