用了很久的点分治板子突然想到找重心好像有问题
int get_core(int u, int f, int all) {
int core = son_siz[u] = (siz[u] = 1) - 1;
for (const int& v : e[u])
if (v != f && !arr[v]) {
int res = get_core(v, u, all);
siz[u] += siz[v], son_siz[u] = std::max(son_siz[u], siz[v]);
core = !core || son_siz[res] < son_siz[core] ? res : core;
}
son_siz[u] = std::max(son_siz[u], all - siz[u]);
return !core || son_siz[u] < son_siz[core] ? u : core;
}
void sol(int u) {
arr[u] = true;
//...
for (const int& v : e[u])
if (!arr[v])
sol(get_core(v, 0, siz[v]));
}
设当前分治中心为 u ,这个分治中心是在以 x 作为根时 get_core 找到的重心。那么与 u 有连边的点 v 有可能是 u 的父亲,siz[v] 比真正以 u 为根时的 v 的子树大小要大。然后找重心应该就g了。
但做题到目前为止还没有出 TLE。
求证明正确性或 Hack 。