There is a bi-directional graph with n
vertices, where each vertex is labeled from 0
to n - 1
(inclusive). The edges in the graph are represented as a 2D integer array edges
, where each edges[i] = [ui, vi]
denotes a bi-directional edge between vertex ui
and vertex vi
. Every vertex pair is connected by at most one edge, and no vertex has an edge to itself.
You want to determine if there is a valid path that exists from vertex source
to vertex destination
.
Given edges
and the integers n
, source
, and destination
, return true
if there is a valid path from source
to destination
, or false
otherwise__.
Example 1:
Input: n = 3, edges = [[0,1],[1,2],[2,0]], source = 0, destination = 2 Output: true Explanation: There are two paths from vertex 0 to vertex 2: - 0 -> 1 -> 2 - 0 -> 2
Example 2:
Input: n = 6, edges = [[0,1],[0,2],[3,5],[5,4],[4,3]], source = 0, destination = 5 Output: false Explanation: There is no path from vertex 0 to vertex 5.
Constraints:
1 <= n <= 2 * 105
0 <= edges.length <= 2 * 105
edges[i].length == 2
0 <= ui, vi <= n - 1
ui != vi
0 <= source, destination <= n - 1
program main
implicit none
integer, parameter :: n = 3
integer, parameter :: edges(n, n) = reshape([&
& 0, 1, 2, &
& 1, 2, 0, &
& 2, 0, 1], shape(edges))
integer, parameter :: source = 0
integer, parameter :: destination = 2
write(*, '(L1)') validPath(edges, n, source, destination)
contains
function validPath(edges, n, source, destination) result(valid)
implicit none
integer, intent(in) :: n
integer, intent(in) :: edges(:, :)
integer, intent(in) :: source
integer, intent(in) :: destination
logical :: valid
integer :: i, j
valid = .false.
do i = 0, n - 1
do j = 0, n - 1
if (edges(i, j) == 1) then
if (i == source .and. j == destination) then
valid = .true.
end if
end if
end do
end do
end function validPath
end program main
F
module BidirectionalGraph
implicit none
private
public :: has_path
contains
logical function has_path(n, edges, source, destination) result(has_path)
integer, intent(in) :: n
integer, intent(in) :: edges(:, :)
integer, intent(in) :: source
integer, intent(in) :: destination
integer :: i, j, k
logical :: visited(n)
integer :: parent(n)
has_path = .false.
! Initialize visited and parent arrays
visited = .false.
parent = -1
! Set source vertex as visited and parent to -1
visited(source) = .true.
parent(source) = -1
! Perform BFS from source vertex
call bfs(n, edges, source, visited, parent)
! Check if destination vertex is visited
if (visited(destination)) then
! Find path from source to destination
k = destination
do while (k /= -1)
write (*, *) k
k = parent(k)
end do
has_path = .true.
end if
contains
! Breadth-First Search (BFS)
subroutine bfs(n, edges, source, visited, parent)
integer, intent(in) :: n
integer, intent(in) :: edges(:, :)
integer, intent(in) :: source
logical, intent(inout) :: visited(n)
integer, intent(inout) :: parent(n)
integer :: i, j, k
integer :: queue(n)
integer :: front, rear
! Initialize queue and counters
front = 1
rear = 0
queue(1) = source
! Loop until queue is empty
do while (front <= rear)
! Dequeue vertex and mark as visited
k = queue(front)
front = front + 1
visited(k) = .true.
! Loop through neighbors of dequeued vertex
do i = 1, n
j = edges(k, i)
if (.not. visited(j)) then
! Enqueue neighbor and set parent
rear = rear + 1
queue(rear) = j
parent(j) = k
end if
end do
end do
end subroutine bfs
end function has_path
end module BidirectionalGraph
! Test program
program test
use BidirectionalGraph
implicit none
integer :: n, source, destination
integer, allocatable :: edges(:, :)
logical :: has_path
! Test case 1
n = 3
allocate(edges(n, n))
edges = reshape([0, 1, 1, 2, 2, 0], shape(edges))
source = 0
destination = 2
has_path = has_path(n, edges, source, destination)
if (has_path) then
write (*, *) "Valid path exists from", source, "to", destination
else
write (*, *) "No valid path exists from", source, "to", destination
end if
! Test case 2
n = 6
allocate(edges(n, n))
edges = reshape([0, 1, 0, 2, 1, 3, 2, 4, 3, 5, 4, 5, 0], shape(edges))
source = 0
destination = 5
has_path = has_path(n, edges, source, destination)
if (has_path) then
write (*, *) "Valid path exists from", source, "to", destination
else
write (*, *) "No valid path exists from", source, "to", destination
end if
! Test case 3
n = 7
allocate(edges(n, n))
edges = reshape([0, 1, 0, 2, 1, 3, 2, 4, 3, 5, 4, 6, 5, 6,
temp.f95:8:77: 8 | logical function has_path(n, edges, source, destination) result(has_path) | 1 Error: RESULT variable at (1) must be different than function name temp.f95:9:32: 9 | integer, intent(in) :: n | 1 Error: Unexpected data declaration statement in CONTAINS section at (1) temp.f95:10:42: 10 | integer, intent(in) :: edges(:, :) | 1 Error: Unexpected data declaration statement in CONTAINS section at (1) temp.f95:11:37: 11 | integer, intent(in) :: source | 1 Error: Unexpected data declaration statement in CONTAINS section at (1) temp.f95:12:42: 12 | integer, intent(in) :: destination | 1 Error: Unexpected data declaration statement in CONTAINS section at (1) temp.f95:13:26: 13 | integer :: i, j, k | 1 Error: Unexpected data declaration statement in CONTAINS section at (1) temp.f95:14:29: 14 | logical :: visited(n) | 1 Error: Explicit array shape at (1) must be constant of INTEGER type and not UNKNOWN type temp.f95:15:28: 15 | integer :: parent(n) | 1 Error: Explicit array shape at (1) must be constant of INTEGER type and not UNKNOWN type temp.f95:17:17: 17 | has_path = .false. | 1 Error: Symbol ‘has_path’ at (1) has already been host associated temp.f95:20:25: 20 | visited = .false. | 1 Error: Unexpected assignment statement in CONTAINS section at (1) temp.f95:21:19: 21 | parent = -1 | 1 Error: Unexpected assignment statement in CONTAINS section at (1) temp.f95:24:32: 24 | visited(source) = .true. | 1 Error: Unexpected assignment statement in CONTAINS section at (1) temp.f95:25:27: 25 | parent(source) = -1 | 1 Error: Unexpected assignment statement in CONTAINS section at (1) temp.f95:28:51: 28 | call bfs(n, edges, source, visited, parent) | 1 Error: Unexpected CALL statement in CONTAINS section at (1) temp.f95:31:38: 31 | if (visited(destination)) then | 1 Error: Unexpected block IF statement in CONTAINS section at (1) temp.f95:33:27: 33 | k = destination | 1 Error: Unexpected assignment statement in CONTAINS section at (1) temp.f95:34:30: 34 | do while (k /= -1) | 1 Error: Unexpected DO statement in CONTAINS section at (1) temp.f95:35:30: 35 | write (*, *) k | 1 Error: Unexpected WRITE statement in CONTAINS section at (1) temp.f95:36:29: 36 | k = parent(k) | 1 Error: Unexpected assignment statement in CONTAINS section at (1) temp.f95:37:15: 37 | end do | 1 Error: Expecting END MODULE statement at (1) temp.f95:38:21: 38 | has_path = .true. | 1 Error: Symbol ‘has_path’ at (1) has already been host associated temp.f95:39:11: 39 | end if | 1 Error: Expecting END MODULE statement at (1) temp.f95:41:12: 41 | contains | 1 Error: Unexpected CONTAINS statement in CONTAINS section at (1) temp.f95:80:7: 80 | end function has_path | 1 Error: Expecting END MODULE statement at (1) temp.f95:4:22: 4 | public :: has_path | 1 Error: Symbol ‘has_path’ at (1) has no IMPLICIT type temp.f95:85:9: 85 | use BidirectionalGraph | 1 Fatal Error: Cannot open module file ‘bidirectionalgraph.mod’ for reading at (1): No such file or directory compilation terminated.
def mem_sticks_crash(memory1, memory2):
crash_time = 1
while True:
if memory1 >= memory2:
if memory1 >= crash_time:
memory1 -= crash_time
else:
break
else:
if memory2 >= crash_time:
memory2 -= crash_time
else:
break
crash_time += 1
return [crash_time, memory1, memory2]
The algorithm starts with a crashTime counter initialized to 1. Then we enter an infinite loop where we compare the available memory on both sticks. If the memory of stick 1 is greater or equal to stick 2, we try to allocate crashTime bits to it, but only if it has enough bits. If it doesn't have enough bits, we break the loop; otherwise, we subtract the bits used from it. We do the same for the memory stick with the lesser memory. Finally, we increment the crashTime counter by 1 at each iteration. When the loop breaks, the function returns an array containing crashTime, and the memory states of both memory sticks at the time of the crash. The algorithm is the same for all languages, with only minimal syntax adjustments.
#include <vector>
std::vector<int> memSticksCrash(int memory1, int memory2) {
int crashTime = 1;
while (true) {
if (memory1 >= memory2) {
if (memory1 >= crashTime) {
memory1 -= crashTime;
} else {
break;
}
} else {
if (memory2 >= crashTime) {
memory2 -= crashTime;
} else {
break;
}
}
crashTime++;
}
return {crashTime, memory1, memory2};
}
The algorithm starts with a crashTime counter initialized to 1. Then we enter an infinite loop where we compare the available memory on both sticks. If the memory of stick 1 is greater or equal to stick 2, we try to allocate crashTime bits to it, but only if it has enough bits. If it doesn't have enough bits, we break the loop; otherwise, we subtract the bits used from it. We do the same for the memory stick with the lesser memory. Finally, we increment the crashTime counter by 1 at each iteration. When the loop breaks, the function returns an array containing crashTime, and the memory states of both memory sticks at the time of the crash. The algorithm is the same for all languages, with only minimal syntax adjustments.