Алгоритм лінійного маркування часу для дерева?


12

У мене є непряме дерево, вершини якого я хочу маркувати. Листові вузли повинні бути позначені одним. Потім, припустимо, листя видалили. На дереві, що залишилося, листя повинні бути позначені двома. Цей процес триває очевидним чином, поки всі вершини не мають мітки. Причиною цього я є те, що я хочу зберігати вершини в черзі і проходити через них "виходить першим". Чи є простий спосіб зробити це час?O(n+m)

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

Іншою ідеєю було спочатку знайти все листя, а потім зробити BFS з кожного листа. Це не дає мені бажаного рішення. Наприклад, розглянемо такий собі "графік корони", як на малюнку нижче. Показано потрібне рішення, але запуск BFS з кожного аркуша призведе до лише двох використаних міток.

введіть тут опис зображення

В ідеалі алгоритм лінійного часу також було б легко пояснити та реалізувати.

Відповіді:


8

Коріння дерев

Ви можете використовувати чергу пріоритетів, щоб вирішити це в :O(E+VlogV)

  • Поставте всі вершини в черзі пріоритету, пріоритет - їх ступінь.
  • Поки черга не порожня:
    • Видаліть вершину мінімального пріоритету, яка повинна бути (або в самому кінці).1 0v10
    • Нехай , де переходить всі вихідні сусіди .σ(v)=1+maxσ(u)uv
    • Відніміть з пріоритету унікального сусіда, що залишився (якщо він є).1u

Насправді нам не потрібна черга з пріоритетом, і цей алгоритм можна реалізувати, використовуючи просту чергу в часі :O(E+V)

  • Ініціалізуйте масив довжиною зі ступенями всіх вершин.V
  • Ініціалізуйте ще один масив довжиною з "живим".V
  • Перейти відразу через перший масив, і натиснути всі вершини ступеня в чергу.1
  • Поки черга не порожня:
    • Pop a vertex .v
    • Нехай , де переходить всі вихідні сусіди .σ(v)=1+maxσ(u)uv
    • Позначити як "мертвого".v
    • Якщо має деякого "живого" сусіда , відніміть від ступеня .vu1u
    • Якщо новий ступінь дорівнює , натисніть до черги.u1u

Укорінені дерева

Використовуйте натомість DFS. Ось ескіз алгоритму.

  • Давши вузол , якщо - лист, встановіть .vvd(v)=1
  • Якщо - не листочок, запустіть алгоритм на всіх його дітях, а потім нехай , де переходить набір усіх дітей.vd(v)=1+maxd(u)u

Ви запускаєте цей алгоритм у корені.


Чи це правильно? Розглянемо дерево 1-> 2-> 3-> 4-> 5, де 1 - корінь. 2 має отримувати мітку 1, а ви даєте 3? Або під дітьми ви маєте на увазі сусідів? З якого вузла ми починаємо dfs відтоді?
Knoothe

Моя реалізація "вимкнена одним", але згідно з вашим описом, має отримати етикетку , оскільки вам потрібно видалити , потім , потім , і тільки потім стає листочком. 245432
Yuval Filmus

Я не задавав питання :-). Я тлумачив питання так: Ненаправлене дерево. Позначте все листя. Видаліть їх. Рекурсуйте на отриманому дереві. У такому випадку дерево насправді 1-2-3-4-5, крок 1, ви видаляєте 1 і 5, потім 2 і 4, а потім 3. Дивіться абзац про "графік крони". Це один із класичних алгоритмів пошуку центру дерева.
Knoothe

1 - не листочок. Це далеко не листя, це корінь. Я трактував питання як націлювання на вкорінені дерева. Можливо, нам слід чекати, коли ОП відповість.
Yuval Filmus

2
@YuvalFilmus, просто щоб кинути свої 2 центи, чи не повинен це бути ? Листя - , якщо видалити їх, то нових листків має бути , тож це міра кількості шарів, які потрібно видалити, перш ніж вершина стане листям. З min будь-яка вершина, що прилягає до листка, отримує 2, але вона може не стати листочком, коли листя видаляються. У цьому реченні було занадто багато листків. Мені потрібна мітла. 1+max{d(u)}12
Люк Матьєсон

2

Відверта відповідь така:

  • Перетворіть це у спрямований графік, де у нас є ребро від кожного вузла до його батьківського . Зауважте, що ви отримуєте даг (спрямований ациклічний графік).(u,v)uv

  • Топологічно сортуйте графік.

  • Скануйте вершини в упорядкованому порядку. Позначте кожну вершину однією з найбільших міток на своїх попередниках. Оскільки ми скануємо в топологічному порядку, всі попередники вже отримали мітку, перш ніж ми спробуємо позначити .vv

Кожен з цих кроків може бути виконаний за час , тому загальний час роботи - . Я згадую цей альтернативний підхід лише у випадку, якщо вам зрозуміло, що це концептуально простіше зрозуміти, ніж відповідь Юваля.O(n+m)O(n+m)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.