Поиск в глубину


Поиск в глубину также используется для нахождения путей в графе, для просчета разных величин для использования в других алгоритмах в будущем. Алгоритм использует стек для хранения вершин и может быть представлен следующим образом:
#include<stdio.h>

int MAXN = 100;//Максимальное число вершин
int MAXM = 100;//Максимальное число ребер
int minpath[MAXN];//Массив расстояний до i-ой вершины
int n;//Число вершин
int m;//Число ребер
int first;//Начальная вершина

int b[MAXM];//b[i] - куда ведет ребро i
int bc;//количество ребер
int last[MAXN];//Последнее ребро, исходящее из вершины
int prev[MAXM];
/*prev[i] - предыдущее ребро, исходящее из той же вершины, что и ребро i.*/

void dfs(int p; int len)
{//Передаем вершину и новый путь до нее
    if (minpath[p] != -1 && len < minpath[p])
        return;
    //Проверяем, уменьшим ли мы минимальный путь до это вершины
    minpath[p] = len;
    //Устанавливаем новый минимальный путь
    
    int i = last[p];
    //Начинаем перебирать ребра, начиная с последнего, исходящего из p
    while (i != -1)
{//Пока не дошли до последнего ребра
        dfs(b[i], len + 1);
        //Запускаем рекурсию в вершину, в которое ведет ребро i

        i = prev[i];
        //Переходим к предыдущему ребру.
    }
}

int main()
{
    scanf(%d%d%d”, &n, &m, &first);
    //Читаем количество вершин, ребер и начальную вершину

    for (int i = 0; i < n; i++)
{
        minpath[i] = -1;
        last[i] = -1;
    }
    /*Устанавливаем значения минимальных путей и отсутствие ребер из каждой вершину.*/

    //Читаем список ребер:
    for (int i = 0; i < m; i++)
{
        int l, r;
        scanf(%d%d”, &l, &r);
        
        bc++;
        b[bc] = r;
        //заносим вершину назначения данного ребра в массив
        prev[bc] = last[x];
        //Устанвливаем предыдущее ребро, как последнее, исходящее из x

        last[x] = bc;
        //Теперь последнее ребро – то, которое мы только что добавили.
    }

    dfs(first, 0);
    //Запускаем dfs из первой вершины
    /*Сейчас в массиве minpath будут расстояния от вершины first до всех остальных вершин*/
}
Модификации
Любой из выше приведенных алгоритмов может быть модифицирован для просчета разных величин, которые потом могут быть использованы в других алгоритмах, например:
  • Для поиска не только кратчайшего пути, но и вершин, по которым нужно идти, чтобы получить этот кратчайший путь (используется, например, в алгоритме нахождения максимального потока)
  • В поиске в глубину можно для каждой вершины запоминать время выхода из нее – для алгоритма нахождения минимального общего предка в графе-дереве.
  • Оба алгоритма могут быть использованы для нахождения циклов в графе.
  • Поиск в глубину может использоваться для топологической сортировки графа.
Эти два алгоритма являются базовыми при изучении графов и алгоритмов на них.

Комментариев нет:

Отправить комментарий