Як знайти суперзірку в лінійний час?


28

Розгляньте спрямовані графіки. Ми називаємо вузол v superstar тоді і тільки тоді, коли до нього не можна дістатися жодного іншого вузла, але всі інші вузли мають край до . Формально:v

v superstar :⟺outdeg(v)=0indeg(v)=n1

з кількістю вузлів у графі. Наприклад, на графіку нижче невиконаний вузол - це суперзірка (а інші вузли - ні).n

Суперзірка
[ джерело ]

Як можна визначити всіх суперзірок у спрямованих графах за час? Зі звичайних кандидатів можна вибрати відповідне графічне зображення ; будь ласка, утримайтеся від використання представлень, які переносять складність проблеми на попередню обробку.O(n)

Ніяких припущень щодо щільності не можна робити. Ми не припускаємо, що графік містить суперзірку; якщо його немає, алгоритм повинен його розпізнати.

Позначення : - кількість вузлів вихідних країв, подібний для вхідних ребер.i n d e goutdegindeg


1
Чи дозволено нам там, де є ребрами, чи нам потрібно дивитись лише на ребра на кожній вершині? k O ( 1 )O(n+k)kO(1)
Кевін

@Kevin Ні, - сувора вимога. Щодо другого питання: я навіть не знаю, що це ще потрібно, але ви, звичайно, не можете зробити більше. O(n)
Рафаель

Чи знаєте ви відповідь? Чи можна це зробити в ? O(n)
Дейв Кларк

@DaveClarke: Так, так.
Рафаель

Вам слід додатково обмежити представництво; лінійний алгоритм неможливий для списку суміжності (просто для підтвердження того, що вершина є суперзіркою, можливо, вам доведеться пройти весь список у кожній вершині).
Жил "ТАК - перестань бути злим"

Відповіді:


18

Ми можемо усунути всі вершини, крім однієї, перевіривши наявність ребер оскільки ми можемо усунути одну можливість для кожного ребра, який ми перевіряємо. Зокрема, якщо є край, що йде від до , ми усуваємо і переходимо до (оскільки з нього можна дістати іншу вершину); якщо ні, то ми усуваємо (оскільки це не може бути досягнуто з ). Як тільки ми дістаємося до останньої вершини, будь-яку вершину не буде усунено, слід порівнювати один з одним вершину (переконайтеся, що дотримується умова суперзірки: є край, що входить, але не виходить), поки він не буде усунутий або підтверджений як суперзірка. Деякі псевдокоди:x y x y y xn1xyxyyx

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 позначає край:

12341101210131114110

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

Почнемо з перегляду вершин 1 і 2.

12341101210131114110
Зелене число показує, що є край від 2 до 1, тому ми усуваємо 2 і шукаємо край від 3 до 1:

12341101210131114110

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

12341101210131114110

Існує ребро від 4 до 3, тому ми усуваємо 4. На цьому етапі ми усунули всі вершини, крім однієї (3), тому перевірте його краї та подивіться, чи відповідає він:

12341101210131114110

Є край від 1 до 3, але не зворотний, тому 3 все ще є кандидатом.

12341101210131114110

Також є край від 2 до 3, але не зворотний, тому 3 все ще є кандидатом.

12341101210131114110

Є край від 4 до 3, але не 3 до 4; що завершує нашу перевірку 3-х країв, і ми виявили, що це насправді суперзірка.

Оскільки ми усуваємо одну вершину як можливу суперзірку на кожній з перших перевірок ребра , найкращим випадком є ​​те, що а перевірка усуває кінцеву вершину на складність . У гіршому випадку (остання або друга-остання вершина - це суперзірка, або остаточна перевірка дискваліфікує її), після першого порівняння ми порівнюємо кандидата з більшою кількістю вершин на , для найгірша складність ( ). Отже, цей алгоритм .n n n - 1 2 × ( n - 1 ) 3 n - 3 O ( n ) Θ ( n )n1nnn12×(n1)3n3O(n)Θ(n)


8

Це не проблема знаменитостей ?

Буде лише одна суперзірка (знаменитість), якщо є.

iA[i,j]=1ij0 . (Я здогадуюсь, що це дозволено).

A[i,j]O(1)A[i,j]=1iA[i,j]=0j

Ведіть список поточних кандидатів, виключаючи один за одним. Пов'язаного списку має бути достатньо.

Наприкінці ви можете перевірити, чи справді ваш кандидат суперзірка.

O(n)


(i,j)

3
@Raphael: Просто виберіть перших двох кандидатів із пов'язаного списку. (голова і голова-> далі).
Ар'ябхата

6

Ця відповідь стосується версії запитання, де можливе будь-яке представлення графіка, а не поточної версії питання.

  • Зберігайте свій графік як пару списку суміжності та списку зворотних суміжностей, де кожен список додатково містить довжину списку, отже, і число, що знаходиться поза межами, і відповідно.

  • O(|E|)

  • 0n1O(|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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.