Задача 2 — Ранг графа

Дан неориентированный граф. Ранг вершины — её степень. Ранг графа = max (rk(u) + rk(v)) по всем рёбрам (u,v). Найти ранг графа.

Определения с иллюстрацией

Степень (ранг) вершины rk(v) — сколько рёбер из неё выходит

0 1 2 3 4 deg 3 deg 1 deg 1 deg 2 deg 1

Рёбра графа: 0-1, 0-2, 0-3, 3-4

Каждое ребро (u,v) добавляет +1 к степени обоих концов.

вершина01234
deg31121

У вершины 0 три ребра (к 1, 2, 3); у вершины 3 — два (к 0 и 4).

Ранг графа — максимум суммы степеней концов, по всем рёбрам

0 1 2 3 4
реброdeg u + deg vсумма
0 – 13 + 14
0 – 23 + 14
0 – 33 + 25 ← max
3 – 42 + 13

Ранг графа = 5 (жирное ребро 0–3).

⚠ Главная ловушка: максимум берётся по рёбрам, а не по любым парам вершин. Вершины 0 (deg 3) и 4 (deg 1) не соединены ребром → пару (0, 4) брать нельзя, даже если её сумма казалась бы выгодной. Поэтому нельзя «просто найти две вершины с наибольшими степенями» — они обязаны быть соединены.

Ход решения

Наблюдение: сам граф как структуру (список смежности / матрицу) хранить не нужно. Нужны только: массив степеней и список рёбер — а список рёбер уже есть на входе.

Алгоритм — два прохода по рёбрам

Почему именно два прохода, а не один: степени должны быть досчитаны полностью до того, как берём суммы. В одном цикле на момент первого ребра степени ещё не готовы → получишь неверный максимум.

Асимптотика

Время O(|V| + |E|)   Память O(|V|)
Два прохода по рёбрам — O(|E|), создание массива степеней — O(|V|).

Код (Python)

def graph_rank(n, edges):
    # n — число вершин (нумерация 0..n-1), edges — список пар (u, v)
    deg = [0] * n

    # проход 1: степени
    for u, v in edges:
        deg[u] += 1
        deg[v] += 1

    # проход 2: максимум суммы степеней концов ребра
    best = 0
    for u, v in edges:
        best = max(best, deg[u] + deg[v])

    return best

Подводные камни (что спросят / на чём падают)

Мини-проверка себя