Запустим пошук в глибину на орієнтованому графі, розглядаючи його як несвязний. Для цього будемо використовувати масив , в якому зберігаються кольори вершин графа:
used[v] = 0 — вершина біла, ще не відвідана;
used[v] = 1 — вершина сірий, в неї вже увійшли, але обробка нащадків ще не завершена;
used[v] = 2 — вершина чорний, вона і всі її нащадки повністю оброблені.
Цикл в орієнтованому графі існує, якщо при пошуку в глибину виявлено ребро, що веде в сіру вершину.
Приклад
Приклади графів, наведені в умові задачі, мають наступний вигляд:
Реалізація алгоритму
Оголосимо матрицю суміжності і масив станів вершин .
#define MAX 51
int g[MAX][MAX], used[MAX];Функція dfs виконує обхід графа в глибину, починаючи з вершини .
void dfs(int v)
{Позначаємо вершину як сіру, ми увійшли в неї.
used[v] = 1;Перебираємо всі вершини, в які можна потрапити з вершини .
for (int i = 1; i <= n; i++)З в існує ребро, якщо g[v][i] = 1.
if (g[v][i])
{Якщо вершина сіра, то в пошуку в глибину ми увійшли в сіру вершину — знайдено цикл.
if (used[i] == 1) flag = 1;Якщо вершина біла, то вона ще не відвідана. Продовжуємо пошук в глибину з неї.
else if (used[i] == 0) dfs(i);Якщо вершина чорна, то нічого не робимо.
}Після завершення обробки всіх синів вершини , позначаємо її як чорною.
used[v] = 2;
}Основна частина програми. Читаємо матрицю суміжності.
scanf("%d", &n);
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
scanf("%d", &g[i][j]);Запускаємо пошук в глибину на орієнтованому графі (як на несвязному).
flag = 0;
for (i = 1; i <= n; i++)
if (used[i] == 0) dfs(i);Виводимо відповідь.
printf("%d\n", flag);Java реалізація
import java.util.*;
public class Main
{
static int g[][], used[];
static int n, flag;
static void dfs(int v)
{
// позначаємо вершину v як сіру, здійснюємо вхід в v
used[v] = 1;
// намагаємося піти з v в i, i = 1,2,...,n
for (int i = 1; i <= n; i++)
// якщо існує ребро з v в i
if (g[v][i] == 1)
{
// якщо вершина i сіра, то зустрічаємо цикл
if (used[i] == 1) flag = 1;
// якщо вершина i не відвідана, запускаємо dfs звідти
else if (used[i] == 0) dfs(i);
// якщо вершина i чорна (used[i] = 2), нічого не робимо
}
// позначаємо вершину v як чорну, здійснюємо вихід з v
used[v] = 2;
}
public static void main(String[] args)
{
Scanner con = new Scanner(System.in);
n = con.nextInt();
g = new int[n+1][n+1];
used = new int[n+1];
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
g[i][j] = con.nextInt();
flag = 0;
// запускаємо dfs на орієнтованому графі як на несвязному графі
for (int i = 1; i <= n; i++)
if (used[i] == 0) dfs(i);
System.out.println(flag);
}
}