Участник:Siziyman
Версия от 23:13, 9 января 2014; Siziyman (обсуждение | вклад) (Новая страница: «Тут будет черновичок конспекта, который вовремя сдан не был. == Задача о количестве полны...»)
Тут будет черновичок конспекта, который вовремя сдан не был.
Задача о количестве полных подграфов в графе
Дан граф
, в котором вершин. Требуется подсчитать количество полных подграфов графа (такие подграфы также называются кликами — clique).1. Наивное решение - перебор всех возможных подграфов и проверка для каждого, что он является кликой, сложность -
2. Этот алгоритм можно улучшить до
. Для этого нужно в функции перебора хранить маску вершин, которые мы ещё можем добавить. Поддерживая эту маску, можно добавлять только «нужные» вершины, и тогда не нужно будет в конце проверять подграф на то что он — клика. Добавлять вершину можно за , используя побитовое «и» текущей маски и строчки матрицы смежности добавляемой вершины.Решение с meet-in-the-middle
Разбиваем граф
на 2 графа и по вершин. Находим за все клики в каждом из них.Теперь надо узнать для каждой клики графа
количество клик графа , таких, что их объединение — клика. Их сумма и есть итоговый ответ.Для одной клики
графа может быть несколько подходящих клик в . О клике мы "знаем" только маску вершин графа , которые ещё можно добавить. Для каждой такой маски в нужно предподсчитать ответ. С помощью динамического программирования предподсчитаем для каждой маски вершин графа количество клик, вершины которой являются подмножеством выбранной маски. Количество состояний - . Количество переходов: . Асимптотика - .
Для каждой клики (в том числе и пустой) графа прибавим к глобальному ответу предподсчитанное количество клик, которые можно добавить к (В том числе и пустых). Асимптотика: .
Псевдокод подсчёта ответа:
for mаsk = 0 to (1 << N) dp[mask] = 1 + sum( [p[mask & matrix[i] for i = 0 to N if ((mask & ( 1 << i )) > 0)) ans = sum(dp[clique1_mask[i]])
Итоговая сложность: