Как найти суперзвезду за линейное время?

28

Рассмотрим ориентированные графы. Мы называем узел суперзвездой том и только в том случае, если от него невозможно связаться с другим узлом, но все остальные узлы имеют ребро к . Формально:vv v

v супер звезда : ⟺оUTdег(v)знак равно0яNdег(v)знак равноN-1

с число узлов в графе. Например, на приведенном ниже графике незаполненный узел является суперзвездой (а другие узлы - нет).N

Суперзвезда
[ источник ]

Как вы можете определить все суперзвезды в ориентированных графах за время? Подходящее графическое представление может быть выбрано из обычных кандидатов ; пожалуйста, воздержитесь от использования представлений, которые перемещают сложность проблемы к предварительной обработке.О(N)

Никакие предположения относительно плотности не могут быть сделаны. Мы не предполагаем, что граф содержит суперзвезду; если его нет, алгоритм должен его распознать.

Обозначение : - это число исходящих ребер в узле, аналогично для входящих ребер.я н д е гоUTdегяNdег

Рафаэль
источник
1
Разрешено ли нам где - ребра, или нам нужно смотреть только ребер в каждой вершине? k O ( 1 )O(n+k)kO(1)
Кевин
@Kevin Нет, - строгое требование. Что касается второго вопроса: я не знаю, нужно ли это, но вы, конечно, не можете сделать больше. О(N)
Рафаэль
Ты знаешь ответ? Это можно сделать в ? О(N)
Дейв Кларк
@DaveClarke: Да и да.
Рафаэль
Вы должны ограничить представление дальше; линейный алгоритм невозможен для списка смежности (просто чтобы подтвердить, что вершина является суперзвездой, вам может понадобиться пройти весь список в каждой вершине).
Жиль "ТАК - перестань быть злым"

Ответы:

18

Мы можем исключить все, кроме одной из вершин, проверив наличие ребер, потому что мы можем исключить одну возможность для каждого проверяемого ребра. В частности, если существует ребро, идущее от к , мы исключаем и переходим к (так как из него можно добраться до другой вершины); если нет, мы исключаем (так как он не может быть достигнут из ). Как только мы достигаем последней вершины, любую вершину, не удаляемую, следует сравнивать с каждой другой вершиной (убедитесь, что условие суперзвезды поддерживается: есть ребро входящее, но не исходящее), пока оно не будет удалено или подтверждено как суперзвезда. Какой-то псевдокод:x y x y y xN-1ИксYИксYYИкс

vertex superstar(graph g)
    current vertex = first
    # Go through each vertex
    for each subsequent vertex in g ("next")
        # If there's an edge from this to the next, we eliminate this one [move to the new one].
        # If not, we just stay here.
        if edge exists from current to next
            candidate = next
        end if
    end for
    # Now we are on the final remaining candidate, check whether it satisfies the requirements.
    # just a rename for clarity
    candidate = current
    for each other vertex in g
        if edge from current to other exists
            return null 
        else if no edge from other to current
            return null
        end if
    end for
    return candidate
end superstar

Давайте рассмотрим пример, чтобы проиллюстрировать метод. Возьмите этот массив с исходной вершиной сверху и местом назначения сбоку. 1 обозначает ребро:

12341-10121-01311-14110-

Я выделю вершины, которые мы исключили, как потенциальных суперзвезд. Я буду использовать зеленый и красный, чтобы указать края, на которые мы смотрим, когда они есть, и не содержат искомого края, и синий, чтобы указать, где мы уже смотрели.

Начнем с рассмотрения вершин 1 и 2.

12341-10121-01311-14110-
Зеленое число показывает, что есть грань от 2 до 1, поэтому мы исключаем 2 и ищем грань от 3 до 1:

12341-10121-01311-14110-

Мы видим, что такого ребра нет, поэтому исключаем 1 и берем 3 в качестве текущей вершины. Напомним, что мы уже удалили 2, поэтому посмотрим, есть ли преимущество от 4 до 3:

12341-10121-01311-14110-

Имеется ребро от 4 до 3, поэтому мы исключаем 4. На этом этапе мы удалили все, кроме одной из вершин (3), поэтому проверьте его ребра и посмотрите, подходит ли оно:

12341-10121-01311-14110-

Существует преимущество от 1 до 3, но не наоборот, поэтому 3 все еще является кандидатом.

12341-10121-01311-14110-

Существует также преимущество от 2 до 3, но не наоборот, так что 3 все еще является кандидатом.

12341-10121-01311-14110-

Есть преимущество от 4 до 3, но не от 3 до 4; это завершает нашу проверку 3-х ребер, и мы обнаружили, что это на самом деле суперзвезда.

Поскольку мы исключаем одну вершину в качестве возможной суперзвезды в каждой из первых проверок ребер, наилучшим случаем является то, что я проверка исключает конечную вершину для сложности . В худшем случае (последняя или вторая-последняя вершина является суперзвездой, или последняя проверка дисквалифицирует ее), после первых сравнений мы сравниваем кандидата с больше вершин, для в худшем случае сложность ( ). Итак, этот алгоритм .n n n - 1 2 × ( n - 1 ) 3 n - 3 O ( n ) Θ ( n )N-1NNN-12×(N-1)3N-3О(N)Θ(N)

Kevin
источник
8

Разве это не проблема знаменитости ?

Будет только одна суперзвезда (знаменитость), если она есть.

Мы используем представление матрицы смежности, где если существует направленное ребро от до , в противном случае оно равно . (Я предполагаю, что это разрешено).i j 0A[я,J]знак равно1яJ0

Посмотрев на (может быть сделано за время), мы можем исключить хотя бы одного из них в качестве кандидата на звание знаменитости: если , тогда вы можете устранить . Если мы можем исключить .A[я,J]О(1)A[я,J]знак равно1яA[я,J]знак равно0J

Вести список текущих кандидатов, исключая одного за другим. Связанного списка должно быть достаточно.

В конце вы можете проверить, действительно ли ваш кандидат суперзвезда.

Этот алгоритм будет .О(N)

Арьябхата
источник
Как выбрать подходящий в постоянное время? (я,J)
Рафаэль
3
@ Рафаэль: Просто выберите первых двух кандидатов из связанного списка. (голова и голова-> следующая).
Арьябхата
6

Этот ответ касается версии вопроса, где было возможно любое представление графа, а не текущей версии вопроса.

  • Сохраните ваш график в виде пары списков смежности и списка обратных смежностей, где каждый список содержит, кроме того, длину списка, а следовательно, число внешних и внутренних ребер соответственно.

  • Предварительная обработка: вычисляет список обратной смежности (то есть список ребер). Стоимость .О(|Е|)

  • Пройдите по спискам и выберите любой узел, у которого число внешних ребер равно а количество внутренних ребер равно . Стоимость .0N-1О(|N|)

Дэйв Кларк
источник
Хорошо, я вижу, что разрешение любого представления графа слишком слабое. Я ограничил вопрос тем, что я хотел.
Рафаэль
2

Просто для справки, это псевдокод рекурсивной версии того, что написал Кевин.

superstar(V, E) {
  if ( |V| == 1 ) {
    return V.pop
  }

  a = V.pop
  b = V.pop
  if ( (a,b) ∈ E ) {
    no_ss = a
    keep  = b
  }
  else {
    no_ss = b
    keep = a
  }

  s = superstar(V ++ keep)

  return ( s != null && (no_ss, s) ∈ E && !(s, no_ss) ∈ E ) ? s : null
}

hasSuperstar(V, E) = superstar(V, E) != null
Рафаэль
источник