Задача
Дан ориентированный невзвешенный граф. Необходимо определить есть ли в нём циклы, и если есть, то вывести любой из них.
Входные данные
В первой строке находятся два натуральных числа n и m (1 ⩽ n ⩽ 105,1 ⩽ m ⩽ 105) — количество вершин и ребер в графе соответственно. Далее в m строках перечислены рёбра графа. Каждое задаётся парой чисел — номерами начальной и конечной вершин соответственно.
Выходные данные
Если в графе нет цикла, то вывести «NO», иначе вывести «YES» и затем перечислить вершины в порядке обхода цикла.
Тесты
№ |
Входные данные |
Выходные данные |
1 |
2 2
1 2
1 2
|
NO |
2 | 2 2 1 2 2 1 |
YES 1 2 |
3 | 6 7 1 2 1 5 2 3 2 4 4 6 6 5 5 2 |
YES 2 4 6 5 |
4 | 6 6 1 3 2 4 3 4 1 2 3 5 3 6 |
NO |
5 | 4 4 1 3 4 2 2 3 3 4 |
YES 3 4 2 |
Решение
Для решения данной задачи воспользуемся поиском в глубину. Также будем отмечать вершины в различными цветами (0 (белый) — мы еще не посещали вершину, 1 (серый) — посетили вершину и не вышли из нее (зациклились), 2 (черный) — посетили вершину и вышли из неё).
В векторе graph будем хранить сам граф, для проверки на цикличность воспользуемся вектором visited, так же будем хранить порядок обхода графа в векторе path. Так как по условию, в случае нескольких циклов, необходимо вывести любой, то мы будем находить первый и на этом останавливаться, для этого заведем переменную flag, которая равна 1, если цикл уже найден, и равна 0, если цикл еще не найден. В векторе visited будем окрашивать вершину в один из цветов. Если мы захотим посетить 1 (серую) вершину, то это будет означать, что мы отыскали цикл в этой вершине, тогда устанавливаем flag=1.
Осталось лишь вывести его на экран. Для этого воспользуемся вектором path, в котором последний элемент — вершина, в которой цикл. Ищем предпоследнее вхождение этой вершины в векторе path и выводим сам цикл.
Ссылки
Условие задачи на e-olymp
Код программы на ideone