Open In App

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] ]
LightboxInput : src = 1, dest = 3
Output: Yes
Explanation: There is a path from 1 to 3, 1 -> 2 -> 3

Input : src = 0, dest = 3
Output: No
Explanation: There is no path from 0 to 3.

Using Depth First Search - O(V + E) time and O(V) time

The 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:

  1. Mark all vertices as not visited and start DFS from source node.
  2. If current node equals destination, return true.
  3. 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");
}

Output
Yes

Using Breadth First Search - O(V + E) time and O(V) space

The 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:

  1. Initialize an empty queue and push source node into it.
  2. 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.
  3. 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");
}

Output
Yes

Next Article
Article Tags :
Practice Tags :

Similar Reads