Топологически сортируйте этот DAG, чтобы установить некоторый порядок для его узлов. Для каждого узла его значением будет количество исходящих ребер от всех предыдущих узлов минус количество входящих ребер для всех предыдущих узлов и текущего узла. Значение узла "доминатор" всегда равно нулю.
После того, как какой-либо узел помечен как «удаленный», поместите его предшественников и преемников в очередь с приоритетами. Приоритет определяется топологическим порядком сортировки. Обновите значения для всех узлов после «удаленного» узла (добавьте количество входящих узлов и вычтите количество исходящих узлов для этого узла). В то же время (в том же порядке) значение уменьшения для каждого узла между узлом-предшественником в очереди с приоритетами и «удаленным» узлом и значение приращения для каждого узла, начиная с узла-преемника в очереди с приоритетом. Остановитесь, когда значение некоторого узла уменьшится до нуля. Это новый "доминаторный" узел. Если нужны все узлы-доминанты, продолжайте до конца графика.
delete(delNode):
for each predecessor in delNode.predecessors: queue.add(predecessor)
for each successor in delNode.successors: queue.add(successor)
for each node in DAG:
if queue.top.priority == node.priority > delNode.priority:
++accumulator
node.value += accumulator
if node.value == 0: dominatorDetected(node)
if node.priority == delNode.priority:
accumulator += (delNode.predecessors.size - delNode.successors.size)
node.value = -1
if queue.top.priority == node.priority:
queue.pop()
if node.priority < delNode.priority:
--accumulator
if queue.empty: stop
Для случая с несколькими источниками можно использовать один и тот же алгоритм, но хранить список «значений» для каждого узла, по одному значению для каждого источника. Сложность алгоритма составляет O(Nodes * Sources)
, так же как и для самостоятельного поиска по каждому из источников. Но программа может быть сделана более эффективной, если используется векторизация. «значения» могут обрабатываться параллельно с инструкциями SIMD. Современные компиляторы могут выполнять автоматическую векторизацию для достижения этой цели.