Критерий Тарьяна минимальности остовного дерева — различия между версиями
(Дополнение(проверка уникальности минимального остова)) |
Nemzs (обсуждение | вклад) (small-fix) |
||
Строка 1: | Строка 1: | ||
+ | == Критерий Тарьяна == | ||
{{Теорема | {{Теорема | ||
|about= | |about= | ||
Строка 24: | Строка 25: | ||
Поэтому вес получившегося минимального остова <tex>G</tex> будет равен весу <tex>K</tex>, что и требовалось. | Поэтому вес получившегося минимального остова <tex>G</tex> будет равен весу <tex>K</tex>, что и требовалось. | ||
+ | }} | ||
+ | == Уникальность остовного дерева == | ||
{{Задача | {{Задача | ||
− | |definition= | + | |definition=Поиск минимального остовного дерева и проверка его на уникальность. |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
}} | }} | ||
+ | <h4>Алгоритм решения</h4> | ||
+ | Построим минимальное остовное дерево используя [[алгоритм Краскала]]. | ||
+ | Рассмотрим рёбра <tex>e = (u, v)</tex> вне остова в любом порядке. Рассмотрим максимальное ребро на пути <tex>u</tex> и <tex>v</tex> внутри остова: | ||
+ | *Если его вес совпадает с весом ребра, то при добавлении ребра в остов, мы получим остов с циклом на котором несколько рёбер имеют одинаковый вес, значит мы можем удалить любое из них и остовное дерево будет всё ещё минимальным, это нарушает уникальность дерева. | ||
+ | *Если его вес больше ребра, то заменив ребро мы получим остов с большим весом, этот случай не влияет на уникальность. | ||
+ | *Его вес не может быть меньше ребра из остова, иначе мы смогли бы построить минимальное остовное дерево с меньшим весом. | ||
+ | Искать максимальное ребро на пути <tex>u</tex> и <tex>v</tex> в дереве мы можем при помощи алгоритма минимального общего предка(LCA), используя [[метод двоичного подъема]]. | ||
+ | Подвесим дерево за любую вершину, обозначим её за <tex>root</tex>. Построим LCA. Построим массив <tex>Dp</tex>, используя дополнительный массив <tex>up</tex> из LCA. <br><tex>dp[i][j]= \begin{cases} | ||
+ | 0 & j = 0,\\ | ||
+ | max(dp[up[i][j - 1]][j - 1], dp[i][j - 1]) & j \: \textgreater \: 0. | ||
+ | \end{cases}</tex> <br> Храним максимальный вес ребра на пути <tex>i</tex> и <tex>root</tex>, где <tex>i -</tex> номер вершины, <tex>j -</tex> степень подъёма(как в LCA). При запросе рассмотрим два случая: | ||
+ | *Путь ребра содержит корень. Заметим, если разделить путь на две части, то максимальным ребром будет максимальное среди меньших путей. Разобьём путь <tex>u</tex> и <tex>v</tex> на пути <tex>u</tex> и <tex>root</tex>, <tex>v</tex> и <tex>root</tex>. Найдём максимальное ребро на пути <tex>u</tex> и <tex>root</tex>, <tex>v</tex> и <tex>root</tex>, максимальное из них и будет являться ответом. | ||
+ | *Путь ребра не содержит корень. Будем подниматься из нижней вершины до высокой используя массив <tex>Dp</tex>. Какая из вершин выше узнаём используя функцию isUpper(в LCA используется). | ||
<h4>Асимптотика</h4> | <h4>Асимптотика</h4> | ||
Построение минимального остовного дерева работает за <tex>O(N \log N)</tex>, нахождение максимального ребра за <tex>O(\log N)</tex>, максимальное количество рёбер вне остова не больше <tex>N</tex>, каждое ребро проверяется за <tex>O(\log N)</tex>. Построение LCA и дополнительного массива работает за <tex>O(N \log N)</tex>, остов мы построим один раз, LCA тоже один раз, каждое ребро мы не больше одного раза проверим на замену, сложность алгоритма <tex>O(N \log N)</tex>. | Построение минимального остовного дерева работает за <tex>O(N \log N)</tex>, нахождение максимального ребра за <tex>O(\log N)</tex>, максимальное количество рёбер вне остова не больше <tex>N</tex>, каждое ребро проверяется за <tex>O(\log N)</tex>. Построение LCA и дополнительного массива работает за <tex>O(N \log N)</tex>, остов мы построим один раз, LCA тоже один раз, каждое ребро мы не больше одного раза проверим на замену, сложность алгоритма <tex>O(N \log N)</tex>. |
Версия 21:40, 4 января 2017
Содержание
Критерий Тарьяна
Теорема (критерий Тарьяна минимальности остовного дерева): | |||||
Остовное дерево минимально тогда и только тогда, когда любое ребро не из дерева является максимальным на цикле, который образуется при его добавлении в дерево. | |||||
Доказательство: | |||||
Легко заметить, что остовное дерево, не удовлетворяющее условию, не минимально: если существует ребро, не максимальное на образовавшемся цикле, то мы можем уменьшить вес дерева, добавив это ребро и удалив максимальное. Теперь докажем, что дерево , удовлетворяющее условию, минимально:
Для доказательства минимальности алгоритм Краскала, который представляет собой применение леммы о безопасном ребре некоторое число раз. На каждом шаге к строящемуся остову будет добавляться ребро минимального веса, пересекающего некоторый разрез, а этот вес, как было показано в утверждении выше, равен весу ребра из , пересекающего этот разрез. Поэтому вес получившегося минимального остова построим минимальное остовное дерево графа используя будет равен весу , что и требовалось. | |||||
Уникальность остовного дерева
Задача: |
Поиск минимального остовного дерева и проверка его на уникальность. |
Алгоритм решения
Построим минимальное остовное дерево используя алгоритм Краскала. Рассмотрим рёбра вне остова в любом порядке. Рассмотрим максимальное ребро на пути и внутри остова:
- Если его вес совпадает с весом ребра, то при добавлении ребра в остов, мы получим остов с циклом на котором несколько рёбер имеют одинаковый вес, значит мы можем удалить любое из них и остовное дерево будет всё ещё минимальным, это нарушает уникальность дерева.
- Если его вес больше ребра, то заменив ребро мы получим остов с большим весом, этот случай не влияет на уникальность.
- Его вес не может быть меньше ребра из остова, иначе мы смогли бы построить минимальное остовное дерево с меньшим весом.
Искать максимальное ребро на пути метод двоичного подъема.
Подвесим дерево за любую вершину, обозначим её за . Построим LCA. Построим массив , используя дополнительный массив из LCA.
Храним максимальный вес ребра на пути и , где номер вершины, степень подъёма(как в LCA). При запросе рассмотрим два случая:
- Путь ребра содержит корень. Заметим, если разделить путь на две части, то максимальным ребром будет максимальное среди меньших путей. Разобьём путь и на пути и , и . Найдём максимальное ребро на пути и , и , максимальное из них и будет являться ответом.
- Путь ребра не содержит корень. Будем подниматься из нижней вершины до высокой используя массив . Какая из вершин выше узнаём используя функцию isUpper(в LCA используется).
Асимптотика
Построение минимального остовного дерева работает за
, нахождение максимального ребра за , максимальное количество рёбер вне остова не больше , каждое ребро проверяется за . Построение LCA и дополнительного массива работает за , остов мы построим один раз, LCA тоже один раз, каждое ребро мы не больше одного раза проверим на замену, сложность алгоритма .См.также
Литература
- Кормен Т., Лейзерсон Ч., Ривест Р., Штайн К. — Алгоритмы. Построение и анализ.