Вот (попытка) алгоритм полиномиальное время для БМО на произвольное бинарное DAGs .G
Это отвечает на вопрос № 3. (Извините за грязную переписку заранее. :))
Для начала отбросим "навсегда" любую вершину, недоступную из . Мы не заботимся о них, так как они не являются частью любого s - т пути.sst
Затем определите вложенные группы DAG и B , изначально пустые. Тогда для всех вершин v ∈ G - { s , t } ,ABv∈G−{s,t}
Проверьте, существует ли путь от до t . Если это так, добавьте V к A . Если нет, добавьте V к B .vtvAvB
Пусть ребра и B будут те , индуцированных вершинами в пределах каждого набора (на данный момент, игнорировать любые ребра из S к А , от А до т , и от A до B , также отметить , нет ребра от B к т пути строительство).ABsAAtABBt
Затем вычислить транзитивное замыкание . А именно, мы заинтересованы в поиске некоторого множества вершин { * } , которые являются «листья» из суб-DAG А .A{a∗}A
Исправьте все такое . Обратите внимание , что должно быть направлено ребро от с * до т . Это связано с тем, что по построению (i) существует путь s - t через a ∗ , (ii) нет путей от a ∗ до B , и (iii) поскольку A само является DAG, а a ∗ является листом в A нет пути из a ∗ через другую вершину из A в t .a∗a∗tsta∗a∗BAa∗Aa∗At
Теперь также должно быть направленное ребро от каждой вершины в до некоторой вершины в B , или у некоторых из { a ∗ } есть одно ребро к t . В любом случае мы можем удалить любое ребро a ∗ → t .{a∗}B{a∗}ta∗→t
Если = 1, то либо мы должны удалить ребро из уникального a ∗ → t , либо в пути s - t ранее есть вершина, содержащая a ∗, которая имеет два пути к t - один через a ∗ и один непосредственно. В случае, если последнее может иметь место, мы записываем a ∗ → t и действуем «жадно назад» (подробности об этом ниже).|{a∗}|a∗→tsta∗ta∗a∗→t
Если > 1, то мы должны либо удалить все ребра из { a ∗ } → t , либо существует некоторое количество ребер k < | { a ∗ } | ранее в транзитивном замыкании A, которое разъединяет все пути от s через { a ∗ } к t .|{a∗}|{a∗}→tk<|{a∗}|As{a∗}t
Здесь мы используем тот факт, что граф является двоичным DAG.G
Рассмотрим множество предшественников . Поскольку каждая из этих вершин имеет внешнюю степень не более двух, существует ровно три случая:{a∗}
Случай 1. Предшественник имеет затраченной край к некоторой вершине в и из-края до некоторой вершины в B .{a∗}B
В этом случае не имеет значения, удаляем ли мы ребро из предшественника в вершину в или ребро из вершины в { a ∗ } в t . Следовательно, мы можем «пропустить» эту вершину (и проверить, сливается ли обратный путь с путем другой вершины в { a ∗ } ).{a∗}{a∗}t{a∗}
Случай 2. Предшественник имеет выход к вершине в и другой предшественник { a ∗ } .{a∗}{a∗}
In this case, we must either delete both edges from the {a∗} to t, or we can delete a single earlier edge in the path from s to the predecessor that disconnects both paths.
Case 3. A predecessor has an out-edge to two vertices in {a∗}.
This is identical to case 2. It doesn't matter whether we delete one of this predecessor's edges and the corresponding other edges from {a∗} to t, or both of the edges from the {a∗} to t. We just want to know whether we can disconnect the path from s through this predecessor to t with a single edge earlier in the path from s to the predecessor.
В целом, когда мы сканируем в обратном направлении через предшественников в транзитивном замыкании , мы можем жадно отслеживать «лучший на данный момент» выбор. То есть на каждом этапе у нас есть очевидный выбор, который включает в себя удаление некоторого количества ребер, но мы хотим подождать, чтобы увидеть, доступен ли лучший вариант. Как только найден лучший вариант, мы можем «забыть» о предыдущем варианте. Следовательно, достаточно жадного выбора на каждом уровне предшественников (пока мы ждем до конца, чтобы совершить любой выбор).A
Therefore, with some basic memoization, the time and space complexities of this process appear to be at most O(|E|). This leaves out the fact that, while we can locally/greedily identify when we have found a "cheaper choice," it's a priori unclear which previously-recorded edges to remove. Therefore, we record the order in which we check edges as we go. Upon finding a better option, we repeat the search up to this point in order to find which previously-recorded edges to remove. The total time complexity of this step is O(|E|2) and space complexity O(|E|).
Altogether, the time complexity is O(|V|⋅(|V|+|E|)) for initialization, plus O(|V|3) for the transitive closure, plus O(|E|2) for the search. The total time is O(|V|2+|E||V|+|V|3+|E|2)=O(|V|3+|E|2).
Upon completing the process, we obtain the minimum set of edges required to disconnect s from t while preserving at least one out-edge of every vertex in the graph (or we discover that a solution is impossible along the way, and abort).