← Все вопросы

Центр дерева через обрезание листьев слоями: почему центров не больше двух?

Задан 24 месяца назад1.1к просмотров2 ответа
8

Нужно найти центр дерева — вершину (или две) с минимальным эксцентриситетом (минимальным максимальным расстоянием до других вершин). Видел метод «обрезать листья слой за слоем, пока не останется 1 или 2 вершины». Почему этот метод даёт именно центр и почему в конце остаётся не больше двух вершин?

2 ответа

12
✓ Принятый ответ — помог автору

Центр дерева лежит в середине диаметра. Метод «топологической обрезки листьев» находит его так: на каждом слое удаляем все текущие листья (степень 1) одновременно, повторяем. Последние 1 или 2 оставшиеся вершины — центр.

vector<int> treeCenter(int n, vector<int> g[]) {
    if (n == 1) return {0};
    vector<int> deg(n);
    queue<int> leaves;
    for (int v = 0; v < n; v++) {
        deg[v] = g[v].size();
        if (deg[v] == 1) leaves.push(v);
    }
    int remaining = n;
    while (remaining > 2) {
        int sz = leaves.size();
        remaining -= sz;
        while (sz--) {                  // снимаем ВЕСЬ текущий слой листьев
            int v = leaves.front(); leaves.pop();
            for (int u : g[v]) if (--deg[u] == 1) leaves.push(u);
        }
    }
    vector<int> center;
    while (!leaves.empty()) { center.push_back(leaves.front()); leaves.pop(); }
    return center; // 1 или 2 вершины
}

Почему это центр: удаляя слой листьев, мы как бы «сжимаем» дерево к середине самого длинного пути. Эксцентриситет внешних вершин больше, чем у внутренних, и обрезка симметрично уменьшает диаметр на 2 за слой.

Почему ≤ 2: длина диаметра — это число рёбер на самом длинном пути. Если диаметр чётный — у него ровно одна центральная вершина (один центр). Если нечётный — две центральные вершины (два центра, они соседи). Третьего не дано, поэтому обрезка заканчивается на 1 или 2 вершинах.

Сложность O(V) (E = V−1), память O(V).

5

Альтернатива через диаметр напрямую: найти диаметр двумя BFS (получив путь A..B), затем взять его середину — вершину(ы) на позиции ⌊len/2⌋. Для этого надо восстановить сам путь диаметра (через par[]), что чуть возни больше, чем обрезка листьев.

Важно не путать центр (минимум эксцентриситета, середина диаметра) с центроидом (минимум максимального поддерева, размеры ≤ n/2) — это разные вершины и считаются разными алгоритмами. Центр — про расстояния (обрезка листьев / середина диаметра), центроид — про размеры поддеревьев (спуск в тяжёлого ребёнка). Метод «обрезки листьев» даёт именно центр, а не центроид.

Ваш ответ

Войдите, чтобы ответить на вопрос.