Алгоритмы на графах (10-е апреля 2024)
- Вероятностная проверка на 3-связность за O(n+m).
- Построение: остов, случайные веса, dp по остову, чтобы XOR вершин был ноль
- Основная лемма: XOR разреза ноль
- Следствия: мост, 2-разрез, 3-разрез
- В другую сторону XOR не разреза равновероятный
- Задача: как проверить, потеряется ли связность при удалении множества рёбер A, |A|=O(1)?
- Эппштейн: поиск k-го непростого пути.
- Кратчайший путь. Картинка с ответвлениями. Вес ответвлений.
- Какие кандидаты добавятся?
- Персистентная сливаемая куча кандидатов.
- Алгоритм двух китайцев (остовное ориентированное MST за O(mlogn)).
- Основа с вычитанием. O(mn).
- Версия за O(mlogn) для получение веса дерева
- Восстановление рёбер дерева: итеративное расжатие
- Восстановление рёбер дерева: алгоритм Прима на весах "время сжатия"
- Динамическая связность для орграфов
- Просто найти матричку: O(nm/w).
- Только добавления: O(n/w) амортизированно на запрос.
- King,Sagert'1999, fully-dynamic O(n2)-update, O(1)-query for DAG
- Люди сомневаются, что full-dynamic SCC можно за O(m1-eps) и на update, и на query (даёт мощный прогресс в SETH).
− Перерыв −
- Динамическая связность для орграфов (продолжение)
- Shiloach'1981 : решение decremental-SSR (single-source-reachability) за O(q + nm)
- [skipped] Italiano'2001 : храним отложенные операции, оптимум достигается при k=n0.575 отложенных, это следует из уравнение на степень n в умножении матриц w(1,eps,1)=1+2eps
- Динамическая связность и 2-связность в оффлайн за O((n+m)logn).
- Откаты: решение дерева отрезков за O(log2n).
- Упражнение: точки добавляются и удаляются, поддерживать две самые ближайшие.
- Сжатие графа. Решение деревом отрезков за O(logn).
- Упражнение: Обобщение для двусвязности.
- Упражнение: Обобщение для MST.
- Динамическая связность в онлайн за O(log2n)
- Наивное Add = O(1), Del = O(1), Get = O(m)
- Наивное Add = DSU, Del = O(n+m), Get = DSU
- ETT : всё за log, но мы всегда лес
- ETT : напоминание, как это добро хранить в Treap, что нужны отцы, подниматься до корня
- Проблема : как при удалении искать замену?
- Основная идея : переберём рёбра, торчащие из меньшего из кусков, при этом перебирать можно только вершины, из которых что-то торчит (сумма в декартовом дереве больше нуля)
- Как самортизировать? Всем рёбрам, которые перебрали будем понижать "ранг".
- Конструкция: У каждого ребра есть ранг от log2n..0. При добавлении равен log2n.
- Для каждого k = 0..log2n мы поддерживаем ET[k] − MST на рёбрах с рангом 0..k. ET[log2n] = полный остов.
- ET[i] ⊂ ET[i+1]. Если ребро ранга i или не в остовах, или присутствует в ET[i],ET[i+1],ET[i+2]...
- Инвариант: компоненты ET[i] имеют размер не более 2i.
- Поиск замены на уровне j ≥ i:
- ET[j]=A+B, выбрать меньшую половину B
- Понизить ранг рёбрам B до i-1 (|B| ≤ 2i-1, между A и B нет рёбер ранга меньше j).
- Перебирать рёбра ранга j, торчащие из B, понижать им ранг до i-1, если ведут в B, если же ведут в A, добавлять в остовы j..log2n
- Запросы, построение
- База: на каждом уровне каждая вершина лежит в своём декартовом дереве, состоящим только из этой вершины. Рёбер нет.
- Ответ на запрос
get(a,b)
: getRoot(vertexPosition[a, 0]) == getRoot(vertexPosition[b, 0])
- Запрос
add(a, b)
: if (!get(a, b)) { новое ребро = {a, b, rank=0}; makeRoot(a); makeRoot(b); merge(getRoot(a), новое ребро, getRoot(b), новое ребро) }
- Запрос
del(a, b)
: e = ребро; i = rank[e]; if (e не в ET[i]) return; for (j=i..log2n) { ET[j].splitByEdge(e); } найти замену для "e"!
- Дерево доминаторов за O(mlogn).
- Определение доминаторов, естественный поиск за O(mn/w).
- Наша задача не проще LCA.
- Решение для DAG: LCA
- Решение для произвольного графа: LCA много раз (не более 6 фаз)
- Свойства доминаторов: ребро вверх в дерево dfs ; вложенность отношения "доминатор".
- Решение для произвольного графа: через LCA-offline (dfs+DSU) сведение к задаче на пути.
- Решение для задачи на пути.