Find if there is a path between two vertices in a directed graph Last Updated : 14 May, 2025 Comments Improve Suggest changes Like Article Like Report Given a Directed Graph and two vertices src and dest, check whether there is a path from src to dest.Example: Consider the following Graph: adj[][] = [ [], [0, 2], [0, 3], [], [2] ]Input : src = 1, dest = 3Output: YesExplanation: There is a path from 1 to 3, 1 -> 2 -> 3Input : src = 0, dest = 3Output: NoExplanation: There is no path from 0 to 3.Using Depth First Search - O(V + E) time and O(V) timeThe idea is to start from the source vertex and explore as far as possible along each branch before moving backFind if there is a path between two vertices in a directed graphFind if there is a path between two vertices in a directed graph. If during this traversal we encounter the destination vertex, we can conclude that there exists a path from source to destination.Step by step approach:Mark all vertices as not visited and start DFS from source node.If current node equals destination, return true.Otherwise, mark current vertex as visited and recursively check all adjacent vertices.If any recursive call returns true, return true; otherwise, return false. C++ // C++ approach to Find if there is a path // between two vertices in a directed graph #include<bits/stdc++.h> using namespace std; bool dfs(vector<vector<int>> &adj, int curr, int dest, vector<bool> &visited) { // If curr node is the destination, return true if (curr == dest) return true; // Mark curr node as visited visited[curr] = true; // Traverse all adjacent vertices for (int i = 0; i < adj[curr].size(); i++) { int nextVertex = adj[curr][i]; // If an adjacent vertex is not visited, // recursively check it if (!visited[nextVertex]) { if (dfs(adj, nextVertex, dest, visited)) return true; } } // No path found from curr // node to destination return false; } bool isReachable(vector<vector<int>> &adj, int src, int dest) { int n = adj.size(); // Create a vector to keep track of visited vertices vector<bool> visited(n, false); // Call the DFS utility function return dfs(adj, src, dest, visited); } int main() { vector<vector<int>> adj = { {}, {0, 2}, {0, 3}, {}, {2} }; int src = 1, dest = 3; if (isReachable(adj, src, dest)) { cout << "Yes" << endl; } else { cout << "No" << endl; } return 0; } Java // Java approach to Find if there is a path // between two vertices in a directed graph class GfG { static boolean dfs(int[][] adj, int curr, int dest, boolean[] visited) { // If curr node is the destination, return true if (curr == dest) return true; // Mark curr node as visited visited[curr] = true; // Traverse all adjacent vertices for (int i = 0; i < adj[curr].length; i++) { int nextVertex = adj[curr][i]; // If an adjacent vertex is not visited, // recursively check it if (!visited[nextVertex]) { if (dfs(adj, nextVertex, dest, visited)) return true; } } // No path found from curr // node to destination return false; } static boolean isReachable(int[][] adj, int src, int dest) { int n = adj.length; // Create a vector to keep track of visited vertices boolean[] visited = new boolean[n]; // Call the DFS utility function return dfs(adj, src, dest, visited); } public static void main(String[] args) { int[][] adj = { {}, {0, 2}, {0, 3}, {}, {2} }; int src = 1, dest = 3; if (isReachable(adj, src, dest)) { System.out.println("Yes"); } else { System.out.println("No"); } } } Python # Python approach to Find if there is a path # between two vertices in a directed graph def dfs(adj, curr, dest, visited): # If curr node is the destination, return true if curr == dest: return True # Mark curr node as visited visited[curr] = True # Traverse all adjacent vertices for i in range(len(adj[curr])): nextVertex = adj[curr][i] # If an adjacent vertex is not visited, # recursively check it if not visited[nextVertex]: if dfs(adj, nextVertex, dest, visited): return True # No path found from curr # node to destination return False def isReachable(adj, src, dest): n = len(adj) # Create a vector to keep track of visited vertices visited = [False] * n # Call the DFS utility function return dfs(adj, src, dest, visited) if __name__ == "__main__": adj = [ [], [0, 2], [0, 3], [], [2] ] src, dest = 1, 3 if isReachable(adj, src, dest): print("Yes") else: print("No") C# // C# approach to Find if there is a path // between two vertices in a directed graph using System; class GfG { static bool dfs(int[][] adj, int curr, int dest, bool[] visited) { // If curr node is the destination, return true if (curr == dest) return true; // Mark curr node as visited visited[curr] = true; // Traverse all adjacent vertices for (int i = 0; i < adj[curr].Length; i++) { int nextVertex = adj[curr][i]; // If an adjacent vertex is not visited, // recursively check it if (!visited[nextVertex]) { if (dfs(adj, nextVertex, dest, visited)) return true; } } // No path found from curr // node to destination return false; } static bool isReachable(int[][] adj, int src, int dest) { int n = adj.Length; // Create a vector to keep track of visited vertices bool[] visited = new bool[n]; // Call the DFS utility function return dfs(adj, src, dest, visited); } static void Main(string[] args) { int[][] adj = { new int[] {}, new int[] {0, 2}, new int[] {0, 3}, new int[] {}, new int[] {2} }; int src = 1, dest = 3; if (isReachable(adj, src, dest)) { Console.WriteLine("Yes"); } else { Console.WriteLine("No"); } } } JavaScript // JavaScript approach to Find if there is a path // between two vertices in a directed graph function dfs(adj, curr, dest, visited) { // If curr node is the destination, return true if (curr === dest) return true; // Mark curr node as visited visited[curr] = true; // Traverse all adjacent vertices for (let i = 0; i < adj[curr].length; i++) { let nextVertex = adj[curr][i]; // If an adjacent vertex is not visited, // recursively check it if (!visited[nextVertex]) { if (dfs(adj, nextVertex, dest, visited)) return true; } } // No path found from curr // node to destination return false; } function isReachable(adj, src, dest) { let n = adj.length; // Create a vector to keep track of visited vertices let visited = new Array(n).fill(false); // Call the DFS utility function return dfs(adj, src, dest, visited); } const adj = [ [], [0, 2], [0, 3], [], [2] ]; const src = 1, dest = 3; if (isReachable(adj, src, dest)) { console.log("Yes"); } else { console.log("No"); } OutputYes Using Breadth First Search - O(V + E) time and O(V) spaceThe idea is to start from the source vertex and explore all neighboring vertices at the present depth before moving on to vertices at the next level.Step by step approach:Initialize an empty queue and push source node into it.While queue is not empty:Pop the front node from queue. If node is destination node, return true.Otherwise, mark and push all the unvisited adjacent nodes into the queue.If destination node is not reachable, return false. C++ // C++ approach to Find if there is a path // between two vertices in a directed graph #include<bits/stdc++.h> using namespace std; bool isReachable(vector<vector<int>> &adj, int src, int dest) { int n = adj.size(); // Create a vector to keep // track of visited vertices vector<bool> visited(n, false); queue<int> q; // Mark the source node as // visited and enqueue it visited[src] = true; q.push(src); while (!q.empty()) { // Dequeue a vertex int curr = q.front(); q.pop(); // If curr vertex is the destination, return true if (curr == dest) return true; // Get all adjacent vertices of the dequeued vertex for (int i = 0; i < adj[curr].size(); i++) { int nextVertex = adj[curr][i]; // If an adjacent vertex is not visited, // mark it visited and enqueue it if (!visited[nextVertex]) { visited[nextVertex] = true; q.push(nextVertex); } } } // If BFS is complete without visiting // destination, return false return false; } int main() { vector<vector<int>> adj = { {}, {0, 2}, {0, 3}, {}, {2} }; int src = 1, dest = 3; if (isReachable(adj, src, dest)) { cout << "Yes" << endl; } else { cout << "No" << endl; } return 0; } Java // Java approach to Find if there is a path // between two vertices in a directed graph import java.util.*; class GfG { static boolean isReachable(int[][] adj, int src, int dest) { int n = adj.length; // Create a vector to keep // track of visited vertices boolean[] visited = new boolean[n]; Queue<Integer> q = new LinkedList<>(); // Mark the source node as // visited and enqueue it visited[src] = true; q.add(src); while (!q.isEmpty()) { // Dequeue a vertex int curr = q.poll(); // If curr vertex is the destination, return true if (curr == dest) return true; // Get all adjacent vertices of the dequeued vertex for (int i = 0; i < adj[curr].length; i++) { int nextVertex = adj[curr][i]; // If an adjacent vertex is not visited, // mark it visited and enqueue it if (!visited[nextVertex]) { visited[nextVertex] = true; q.add(nextVertex); } } } // If BFS is complete without visiting // destination, return false return false; } public static void main(String[] args) { int[][] adj = { {}, {0, 2}, {0, 3}, {}, {2} }; int src = 1, dest = 3; if (isReachable(adj, src, dest)) { System.out.println("Yes"); } else { System.out.println("No"); } } } Python # Python approach to Find if there is a path # between two vertices in a directed graph from collections import deque def isReachable(adj, src, dest): n = len(adj) # Create a vector to keep # track of visited vertices visited = [False] * n q = deque() # Mark the source node as # visited and enqueue it visited[src] = True q.append(src) while q: # Dequeue a vertex curr = q.popleft() # If curr vertex is the destination, return true if curr == dest: return True # Get all adjacent vertices of the dequeued vertex for i in range(len(adj[curr])): nextVertex = adj[curr][i] # If an adjacent vertex is not visited, # mark it visited and enqueue it if not visited[nextVertex]: visited[nextVertex] = True q.append(nextVertex) # If BFS is complete without visiting # destination, return False return False if __name__ == "__main__": adj = [ [], [0, 2], [0, 3], [], [2] ] src = 1 dest = 3 if isReachable(adj, src, dest): print("Yes") else: print("No") C# // C# approach to Find if there is a path // between two vertices in a directed graph using System; using System.Collections.Generic; class GfG { static bool isReachable(int[][] adj, int src, int dest) { int n = adj.Length; // Create a vector to keep // track of visited vertices bool[] visited = new bool[n]; Queue<int> q = new Queue<int>(); // Mark the source node as // visited and enqueue it visited[src] = true; q.Enqueue(src); while (q.Count > 0) { // Dequeue a vertex int curr = q.Dequeue(); // If curr vertex is the destination, return true if (curr == dest) return true; // Get all adjacent vertices of the dequeued vertex for (int i = 0; i < adj[curr].Length; i++) { int nextVertex = adj[curr][i]; // If an adjacent vertex is not visited, // mark it visited and enqueue it if (!visited[nextVertex]) { visited[nextVertex] = true; q.Enqueue(nextVertex); } } } // If BFS is complete without visiting // destination, return false return false; } static void Main(string[] args) { int[][] adj = new int[][] { new int[] {}, new int[] {0, 2}, new int[] {0, 3}, new int[] {}, new int[] {2} }; int src = 1, dest = 3; if (isReachable(adj, src, dest)) { Console.WriteLine("Yes"); } else { Console.WriteLine("No"); } } } JavaScript // JavaScript approach to Find if there is a path // between two vertices in a directed graph function isReachable(adj, src, dest) { const n = adj.length; // Create a vector to keep // track of visited vertices const visited = new Array(n).fill(false); const q = []; // Mark the source node as // visited and enqueue it visited[src] = true; q.push(src); while (q.length > 0) { // Dequeue a vertex const curr = q.shift(); // If curr vertex is the destination, return true if (curr === dest) return true; // Get all adjacent vertices of the dequeued vertex for (let i = 0; i < adj[curr].length; i++) { const nextVertex = adj[curr][i]; // If an adjacent vertex is not visited, // mark it visited and enqueue it if (!visited[nextVertex]) { visited[nextVertex] = true; q.push(nextVertex); } } } // If BFS is complete without visiting // destination, return false return false; } const adj = [ [], [0, 2], [0, 3], [], [2] ]; const src = 1, dest = 3; if (isReachable(adj, src, dest)) { console.log("Yes"); } else { console.log("No"); } OutputYes Comment More infoAdvertise with us kartik Follow Improve Article Tags : Graph DSA BFS Practice Tags : BFSGraph Similar Reads Depth First Search or DFS for a Graph In Depth First Search (or DFS) for a graph, we traverse all adjacent vertices one by one. When we traverse an adjacent vertex, we completely finish the traversal of all vertices reachable through that adjacent vertex. This is similar to a tree, where we first completely traverse the left subtree and 13 min read DFS in different languageC Program for Depth First Search or DFS for a GraphDepth First Traversal (or DFS) for a graph is similar to Depth First Traversal of a tree. The only catch here is, that, unlike trees, graphs may contain cycles (a node may be visited twice). To avoid processing a node more than once, use a boolean visited array. A graph can have more than one DFS tr 4 min read Depth First Search or DFS for a Graph - PythonDepth First Traversal (or DFS) for a graph is similar to Depth First Traversal of a tree. The only catch here is, that, unlike trees, graphs may contain cycles (a node may be visited twice). To avoid processing a node more than once, use a Boolean visited array. A graph can have more than one DFS tr 4 min read Java Program for Depth First Search or DFS for a GraphDepth First Traversal (or DFS) for a graph is similar to Depth First Traversal of a tree. Prerequisite: Graph knowledge is important to understand the concept of DFS. What is DFS?DFS or Depth First Traversal is the traversing algorithm. DFS can be used to approach the elements of a Graph. To avoid p 3 min read Iterative Depth First Traversal of Graph Given a directed Graph, the task is to perform Depth First Search of the given graph.Note: Start DFS from node 0, and traverse the nodes in the same order as adjacency list.Note : There can be multiple DFS traversals of a graph according to the order in which we pick adjacent vertices. Here we pick 10 min read Applications, Advantages and Disadvantages of Depth First Search (DFS) Depth First Search is a widely used algorithm for traversing a graph. Here we have discussed some applications, advantages, and disadvantages of the algorithm. Applications of Depth First Search:1. Detecting cycle in a graph: A graph has a cycle if and only if we see a back edge during DFS. So we ca 4 min read Difference between BFS and DFS Breadth-First Search (BFS) and Depth-First Search (DFS) are two fundamental algorithms used for traversing or searching graphs and trees. This article covers the basic difference between Breadth-First Search and Depth-First Search.Difference between BFS and DFSParametersBFSDFSStands forBFS stands fo 2 min read Depth First Search or DFS for disconnected Graph Given a Disconnected Graph, the task is to implement DFS or Depth First Search Algorithm for this Disconnected Graph. Example: Input: Disconnected Graph Output: 0 1 2 3 Algorithm for DFS on Disconnected Graph:In the post for Depth First Search for Graph, only the vertices reachable from a given sour 7 min read Printing pre and post visited times in DFS of a graph Depth First Search (DFS) marks all the vertices of a graph as visited. So for making DFS useful, some additional information can also be stored. For instance, the order in which the vertices are visited while running DFS. Pre-visit and Post-visit numbers are the extra information that can be stored 8 min read Tree, Back, Edge and Cross Edges in DFS of Graph Given a directed graph, the task is to identify tree, forward, back and cross edges present in the graph.Note: There can be multiple answers.Example:Input: GraphOutput:Tree Edges: 1->2, 2->4, 4->6, 1->3, 3->5, 5->7, 5->8 Forward Edges: 1->8 Back Edges: 6->2 Cross Edges: 5- 9 min read Transitive Closure of a Graph using DFS Given a directed graph, find out if a vertex v is reachable from another vertex u for all vertex pairs (u, v) in the given graph. Here reachable means that there is a path from vertex u to v. The reach-ability matrix is called transitive closure of a graph. For example, consider below graph: GraphTr 8 min read Variations of DFS implementationsImplementation of DFS using adjacency matrixDepth First Search (DFS) has been discussed in this article which uses adjacency list for the graph representation. In this article, adjacency matrix will be used to represent the graph.Adjacency matrix representation: In adjacency matrix representation of a graph, the matrix mat[][] of size n*n (wh 8 min read Graph implementation using STL for competitive programming | Set 1 (DFS of Unweighted and Undirected)We have introduced Graph basics in Graph and its representations. In this post, a different STL-based representation is used that can be helpful to quickly implement graphs using vectors. The implementation is for the adjacency list representation of the graph. Following is an example undirected and 7 min read Graph implementation using STL for competitive programming | Set 2 (Weighted graph)In Set 1, unweighted graph is discussed. In this post, weighted graph representation using STL is discussed. The implementation is for adjacency list representation of weighted graph. Undirected Weighted Graph We use two STL containers to represent graph: vector : A sequence container. Here we use i 7 min read Like