122 subroutine graph_add_edge(this, source, destination, exists)
123 class(
digraph),
intent(inout) :: this
124 integer,
intent(in) :: source
125 integer,
intent(in) :: destination
126 logical,
intent(out),
optional :: exists
128 if (source < 1 .or. source > this%vertices .or. &
129 destination < 1 .or. destination > this%vertices)
then
133 this%list_sizes(source) = this%list_sizes(source) + 1
134 if (this%list_sizes(source) <= this%vertices)
then
135 if (
present(exists)) exists = this%adjacency_list(source, this%list_sizes(source)) /= 0
136 this%adjacency_list(source, this%list_sizes(source)) = destination
147 logical function graph_has_cycle_dfs(this, start_vertex)
result(has_cycle)
148 class(
digraph),
intent(in) :: this
149 integer,
intent(in) :: start_vertex
151 logical,
allocatable :: visited(:), recursion_stack(:)
153 if (start_vertex < 1 .or. start_vertex > this%vertices)
then
158 allocate(visited(this%vertices), source=.false.)
159 allocate(recursion_stack(this%vertices), source=.false.)
161 has_cycle =
dfs_recursive(this, start_vertex, visited, recursion_stack)
163 deallocate(visited, recursion_stack)
168 recursive logical function dfs_recursive(this, vertex, visited, recursion_stack)
result(has_cycle)
169 class(
digraph),
intent(in) :: this
170 integer,
intent(in) :: vertex
171 logical,
intent(inout) :: visited(:), recursion_stack(:)
172 integer :: neighbor, i
174 visited(vertex) = .true.
175 recursion_stack(vertex) = .true.
177 do i = 1, this%list_sizes(vertex)
178 neighbor = this%adjacency_list(vertex, i)
179 if (neighbor < 1 .or. neighbor > this%vertices) cycle
180 if (.not. visited(neighbor))
then
181 if (
dfs_recursive(this, neighbor, visited, recursion_stack))
then
185 else if (recursion_stack(neighbor))
then
191 recursion_stack(vertex) = .false.
recursive logical function dfs_recursive(this, vertex, visited, recursion_stack)
Internal recursive DFS worker for cycle detection.