- DFS-дерево Пошук в глибину можна застосувати для знаходження компонент зв'язності графа або для побудови...
- побудова каркаса
DFS-дерево
Пошук в глибину можна застосувати для знаходження компонент зв'язності графа або для побудови каркаса точно таким же чином, як пошук в ширину. Поняття прямого і зворотного ребра визначаються так само, як в попередньому розділі і так само доводиться, що прямі ребра при пошуку в глибину утворюють каркас графа. Для зв'язкового графа каркас, одержуваний пошуком в глибину, називається DFS-деревом. DFS-дерево розглядається як кореневе дерево з коренем у стартовій вершині . Це дерево має особливі властивості, на використанні яких засновані численні застосування методу пошуку в глибину. Розглянемо найбільш важливе з цих властивостей.
Щодо будь-якого кореневого остовного дерева все ребра графа, що не належать дереву, можна розділити на дві категорії. Ребро назвемо поздовжнім, якщо одна з його вершин є предком інший, в іншому випадку ребро назвемо поперечним. У прикладі на Мал. 5.2 ребра каркаса виділені жирними лініями, корінь - чорним кружком. Зворотні ребра показані тонкими лініями, з них поздовжніми є ребра , , , А поперечними - ребра , , .
Теорема 1. нехай - зв'язний граф, - DFS-дерево графа . тоді щодо всі зворотні ребра є поздовжніми.
Доказ. Переконаємося спочатку, що після того, як стартова вершина поміщена в стек, на кожному наступному кроці роботи алгоритму послідовність вершин, що зберігається в стеці, утворює шлях з початком в вершині , А всі ребра цього шляху належать дереву. Спочатку це, очевидно, так. Надалі щоразу, коли нова вершина поміщається в стек, до дерева додається пряме ребро , Причому вершина знаходиться в стеці перед вершиною . Значить, якщо вказане властивість мало місце до додавання вершини в стек, то воно збережеться і після додавання. Видалення ж вершини з стека, звичайно, не може порушити цю властивість.
нехай тепер - зворотне ребро. Кожна з вершин і в ході роботи алгоритму коли-небудь виявиться в стеці. Припустимо, виявиться там раніше, ніж . Розглянемо крок алгоритму, на якому поміщається в стек. У цей момент ще перебуває в стеці. Дійсно, вершина виключається з стека тільки тоді, коли в її околиці немає невідвіданих вершин. Але безпосередньо перед приміщенням в стек вершина є новою і належить околі вершини . Таким чином, вершина лежить на шляху, що належить дереву і з'єднує вершини і . Але це означає, що вершина є предком вершини в дереві і, отже, ребро - поздовжнє.
Таким чином, каркас, зображений на Мал. 5.2 , Не міг бути побудований методом пошуку в глибину. До речі, він не міг бути побудований і за допомогою пошуку в ширину (чому?).
глибинна нумерація
Зважаючи на важливість цього методу опишемо ще два варіанти алгоритму пошуку в глибину. Перший з них - рекурсивний, і, як зазвичай, рекурсія дає можливість представити алгоритм в найбільш компактній формі. Для того щоб алгоритм виконував якусь корисну роботу, будемо нумерувати вершини в тому порядку, в якому вони зустрічаються при обході. Номер, який отримують вершиною , Позначається через і називається її глибинним номером. спочатку вважаємо для всіх . Це нульове значення зберігається до тих пір, поки вершина не стає відкритою, в цей момент їй присвоюється її справжній глибинний номер. Таким чином, немає необхідності в будь-якої спеціальної структурі для запам'ятовування нових вершин - вони відрізняються від всіх інших нульовим значенням . Мінлива зберігає поточний номер. Рекурсивна процедура DFSR обходить одну компоненту зв'язності, а алгоритм 1 обходить весь граф і привласнює вершин глибинні номера.
Алгоритм 1. Пошук в глибину з обчисленням глибинних номерів - рекурсивний варіант
- for do
- for do
- if then
Procedure
- for do
- if then
побудова каркаса
Наступний варіант алгоритму пошуку в глибину відрізняється тим, що не використовує стека для зберігання відкритих вершин. Стек потрібен для того, щоб в момент, коли околиця активної вершини досліджена і необхідно зробити "крок назад", можна було визначити вершину, в яку потрібно повернутися. Але це та вершина, яка є батьком вершини в DFS-дереві. Тому, якщо рішення задачі передбачає побудову DFS -дерева, то це дерево можна використовувати і для організації "зворотних рухів" в процесі обходу. Описуваний нижче алгоритм будує каркас довільного графа, кожна компонента зв'язності цього каркаса є DFS-деревом відповідної компоненти зв'язності графа. через позначається батько вершини в цьому DFS-дереві, при цьому для кореня дерева (стартової вершини) вважаємо . Тут і далі в описах алгоритмів інструкція "відкрити (закрити) вершину" означає, що вершина якимось чином позначається як відкрита (закрита).
Алгоритм 2. Пошук в глибину з побудовою каркаса
- позначити всі вершини як нові
- for do
- if вершина нова then
Procedure
- відкрити вершину
- while відкрита do
- if є недосліджене ребро
- then досліджувати ребро
- if вершина нова
- then
- відкрити вершину
- else закрити вершину