Обход в глубину, цвета вершин — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
(Реализация)
Строка 44: Строка 44:
  
 
=== Реализация ===
 
=== Реализация ===
Отличие реализации с цветами от предыдущей лишь в массиве visited, который мы назовем теперь color, и дополнительной ''черной'' "метки". При этом цвета вершин будут заданы следующим образом: ''белый'' - 0, ''серый'' - 1, ''черный'' - 2. Все отличия помечены '''жирным''' шрифтом.
+
Отличие реализации с цветами от предыдущей лишь в массиве visited, который мы назовем теперь color, и дополнительной ''черной'' "метки". При этом цвета вершин будут заданы следующим образом: ''белый'' - 0, ''серый'' - 1, ''черный'' - 2.
  
  vector<'''int'''> '''color''';                          //вектор для хранения информации '''о цвете''' вершин
+
  vector<int> color;                          //вектор для хранения информации о цвете вершин
 
   
 
   
 
  void dfs(int u)               
 
  void dfs(int u)               
 
  {
 
  {
     '''color[u] = 1;                          //раскрашиваем вершину в ''серый'' цвет'''
+
     color[u] = 1;                          //раскрашиваем вершину в ''серый'' цвет
 
     for (v таких, что (u, v) - ребро в G)  //проходим по смежным с u вершинам
 
     for (v таких, что (u, v) - ребро в G)  //проходим по смежным с u вершинам
         if (!color[v])                      //проверяем, не находились ли мы ранее в выбранной вершине, '''условие не требует изменений,'''
+
         if (!color[v])                      //проверяем, не находились ли мы ранее в выбранной вершине, условие не требует изменений,  
             dfs(v);                        '''//поскольку мы считаем вершину "не пройденной" только тогда, когда она ''белого'' цвета, т.е. когда color[v] = 0'''
+
             dfs(v);                        //поскольку мы считаем вершину "не пройденной" только тогда, когда она ''белого'' цвета, т.е. когда color[v] = 0
     '''color[u] = 2;                          //раскрашиваем вершину в ''черный'' цвет'''
+
     color[u] = 2;                          //раскрашиваем вершину в ''черный'' цвет
 
  }
 
  }
 
   
 
   
Строка 60: Строка 60:
 
  {
 
  {
 
     ...                                    //задание графа G с количеством вершин n.
 
     ...                                    //задание графа G с количеством вершин n.
     '''color.assign(n, 0);'''                    //в начале все вершины в графе ''не пройденные'', '''т.е. ''белые''.'''
+
     color.assign(n, 0);                   //в начале все вершины в графе ''не пройденные'', т.е. ''белые''.
 
     for (int i = 0; i < n; ++i)            //проходим по всем вершинам графа...
 
     for (int i = 0; i < n; ++i)            //проходим по всем вершинам графа...
 
         if (!color[i])                    //...не забыв проверить, были мы уже в очередной вершине или нет
 
         if (!color[i])                    //...не забыв проверить, были мы уже в очередной вершине или нет

Версия 21:47, 25 сентября 2011

Обход в глубину (поиск в глубину, англ. Depth-First Search, DFS) - один из основных методов обхода графа, часто используемый для проверки связности, поиска цикла и компонент сильной связности и для топологической сортировки.

Алгоритм

Общая идея

Общая идея алгоритма состоит в следующем: для каждой не пройденной вершины необходимо найти все не пройденные смежные вершины и повторить поиск для них.

Пошаговое представление

  1. Выбираем любую вершину из еще не пройденных, обозначим ее как u.
  2. Запускаем процедуру DFS(u)
    • Помечаем вершину u как пройденную
    • Для каждой не пройденной смежной с u вершиной (назовем ее v) запускаем DFS(v)
  3. Повторяем шаги 1 и 2, пока все вершины не окажутся пройденными.

Реализация

vector<bool> visited;                       //вектор для хранения информации о пройденных и не пройденных вершинах

void dfs(int u)              
{
    visited[u] = true;                      //помечаем вершину как пройденную
    for (v таких, что (u, v) - ребро в G)   //проходим по смежным с u вершинам
        if (!visited[v])                    //проверяем, не находились ли мы ранее в выбранной вершине
            dfs(v);
}

int main()
{
    ...                                     //задание графа G с количеством вершин n.
    visited.assign(n, false);               //в начале все вершины в графе не пройденные
    for (int i = 0; i < n; ++i)             //проходим по всем вершинам графа...
        if (!visited[i])                    //...не забыв проверить, были мы уже в очередной вершине или нет
            dfs(i);
    return 0;
}

Цвета вершин

Зачастую, простой информации "были/не были в вершине" не хватает для конкретных целей.
Поэтому в процессе алгоритма вершинам задают некоторые цвета:

если вершина белая, значит, мы в ней еще не были, вершина не пройдена;
серая - вершина проходится в текущей процедуре DFS;
черная - вершина пройдена, все итерации DFS от нее завершены.

Такие "метки" в основном используются при поиске цикла.

Реализация

Отличие реализации с цветами от предыдущей лишь в массиве visited, который мы назовем теперь color, и дополнительной черной "метки". При этом цвета вершин будут заданы следующим образом: белый - 0, серый - 1, черный - 2.

vector<int> color;                          //вектор для хранения информации о цвете вершин

void dfs(int u)              
{
    color[u] = 1;                           //раскрашиваем вершину в серый цвет
    for (v таких, что (u, v) - ребро в G)   //проходим по смежным с u вершинам
        if (!color[v])                      //проверяем, не находились ли мы ранее в выбранной вершине, условие не требует изменений, 
            dfs(v);                         //поскольку мы считаем вершину "не пройденной" только тогда, когда она белого цвета, т.е. когда color[v] = 0
    color[u] = 2;                           //раскрашиваем вершину в черный цвет
}

int main()
{
    ...                                     //задание графа G с количеством вершин n.
    color.assign(n, 0);                    //в начале все вершины в графе не пройденные, т.е. белые.
    for (int i = 0; i < n; ++i)             //проходим по всем вершинам графа...
        if (!color[i])                    //...не забыв проверить, были мы уже в очередной вершине или нет
            dfs(i);
    return 0;
}

Источники