Longest path in a directed Acyclic graph | Dynamic Programming - GeeksforGeeks

30 Dec, 2021

Given a directed graph G with N vertices and M edges. The task is to find the length of the longest directed path in Graph.Note: Length of a directed path is the number of edges in it. Examples:  
Input: N = 4, M = 5  
Output: 3 The directed path 1->3->2->4 Input: N = 5, M = 8  
Output: 3 
 
Simple Approach: A naive approach is to calculate the length of the longest path from every node using DFS. The time complexity of this approach is O(N2). Efficient Approach: An efficient approach is to use Dynamic Programming and DFS together to find the longest path in the Graph. Let dp[i] be the length of the longest path starting from the node i. Initially all positions of dp will be 0. We can call the DFS function from every node and traverse for all its children. The recursive formula will be:  
dp[node] = max(dp[node], 1 + max(dp[child1], dp[child2], dp[child3]..))  
At the end check for the maximum value in dp[] array, which will be the longest path in the DAG.Below is the implementation of the above approach: 
C++
Java
Python3
C#
Javascript
 

 
 










// C++ program to find the longest
// path in the DAG
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to traverse the DAG
// and apply Dynamic Programming
// to find the longest path
void dfs(int node, vector<int> adj[], int dp[], bool vis[])
{
    // Mark as visited
    vis[node] = true;
 
    // Traverse for all its children
    for (int i = 0; i < adj[node].size(); i++) {
 
        // If not visited
        if (!vis[adj[node][i]])
            dfs(adj[node][i], adj, dp, vis);
 
        // Store the max of the paths
        dp[node] = max(dp[node], 1 + dp[adj[node][i]]);
    }
}
 
// Function to add an edge
void addEdge(vector<int> adj[], int u, int v)
{
    adj[u].push_back(v);
}
 
// Function that returns the longest path
int findLongestPath(vector<int> adj[], int n)
{
    // Dp array
    int dp[n + 1];
    memset(dp, 0, sizeof dp);
 
    // Visited array to know if the node
    // has been visited previously or not
    bool vis[n + 1];
    memset(vis, false, sizeof vis);
 
    // Call DFS for every unvisited vertex
    for (int i = 1; i <= n; i++) {
        if (!vis[i])
            dfs(i, adj, dp, vis);
    }
 
    int ans = 0;
 
    // Traverse and find the maximum of all dp[i]
    for (int i = 1; i <= n; i++) {
        ans = max(ans, dp[i]);
    }
    return ans;
}
 
// Driver Code
int main()
{
    int n = 5;
    vector<int> adj[n + 1];
 
    // Example-1
    addEdge(adj, 1, 2);
    addEdge(adj, 1, 3);
    addEdge(adj, 3, 2);
    addEdge(adj, 2, 4);
    addEdge(adj, 3, 4);
 
    cout << findLongestPath(adj, n);
    return 0;
}






 

 
 










// Java program to find the longest
// path in the DAG
 
import java.util.ArrayList;
 
// graph class
class Graph
{
 
    int vertices;
    ArrayList<Integer> edge[];
 
    Graph(int vertices) 
    {
        this.vertices = vertices;
        edge = new ArrayList[vertices+1];
        for (int i = 0; i <= vertices; i++) 
        {
            edge[i] = new ArrayList<>();
        }
    }
    void addEdge(int a,int b)
    {
        edge[a].add(b);
    }
 
    void dfs(int node, ArrayList<Integer> adj[], int dp[],
                                    boolean visited[])
    {
        // Mark as visited
        visited[node] = true;
 
        // Traverse for all its children
        for (int i = 0; i < adj[node].size(); i++) 
        {
 
            // If not visited
            if (!visited[adj[node].get(i)])
                dfs(adj[node].get(i), adj, dp, visited);
 
            // Store the max of the paths
            dp[node] = Math.max(dp[node], 1 + dp[adj[node].get(i)]);
        }
    }
     
    // Function that returns the longest path
    int findLongestPath( int n)
    {
        ArrayList<Integer> adj[] = edge;
        // Dp array
        int[] dp = new int[n+1];
 
        // Visited array to know if the node
        // has been visited previously or not
        boolean[] visited = new boolean[n + 1];
 
        // Call DFS for every unvisited vertex
        for (int i = 1; i <= n; i++) 
        {
            if (!visited[i])
                dfs(i, adj, dp, visited);
        }
 
        int ans = 0;
 
        // Traverse and find the maximum of all dp[i]
        for (int i = 1; i <= n; i++) 
        {
            ans = Math.max(ans, dp[i]);
        }
        return ans;
    }
}
 
public class Main
{
    // Driver code
    public static void main(String[] args)
    {
        int n = 5;
        Graph graph = new Graph(n);
        // Example-1
        graph.addEdge( 1, 2);
        graph.addEdge( 1, 3);
        graph.addEdge( 3, 2);
        graph.addEdge( 2, 4);
        graph.addEdge( 3, 4);
        graph.findLongestPath(n);
        System.out.println( graph.findLongestPath( n));
 
    }
}
 
// This code is contributed by SumanSaurav






 

 
 










# Python3 program to find the 
# longest path in the DAG 
   
# Function to traverse the DAG 
# and apply Dynamic Programming 
# to find the longest path 
def dfs(node, adj, dp, vis): 
  
    # Mark as visited 
    vis[node] = True
   
    # Traverse for all its children 
    for i in range(0, len(adj[node])):  
   
        # If not visited 
        if not vis[adj[node][i]]:
            dfs(adj[node][i], adj, dp, vis) 
   
        # Store the max of the paths 
        dp[node] = max(dp[node], 1 + dp[adj[node][i]]) 
   
# Function to add an edge 
def addEdge(adj, u, v): 
  
    adj[u].append(v) 
   
# Function that returns the longest path 
def findLongestPath(adj, n): 
  
    # Dp array 
    dp = [0] * (n + 1) 
     
    # Visited array to know if the node 
    # has been visited previously or not 
    vis = [False] * (n + 1)
     
    # Call DFS for every unvisited vertex 
    for i in range(1, n + 1):  
        if not vis[i]: 
            dfs(i, adj, dp, vis) 
      
    ans = 0
   
    # Traverse and find the maximum of all dp[i] 
    for i in range(1, n + 1):  
        ans = max(ans, dp[i]) 
      
    return ans 
  
# Driver Code 
if __name__ == "__main__": 
  
    n = 5
    adj = [[] for i in range(n + 1)]
   
    # Example-1 
    addEdge(adj, 1, 2) 
    addEdge(adj, 1, 3) 
    addEdge(adj, 3, 2) 
    addEdge(adj, 2, 4) 
    addEdge(adj, 3, 4) 
   
    print(findLongestPath(adj, n))
   
# This code is contributed by Rituraj Jain






 

 
 










// C# program to find the longest
// path in the DAG
using System;
using System.Collections.Generic;
 
// graph class
class Graph
{
    public int vertices;
    public List<int> []edge;
 
    public Graph(int vertices) 
    {
        this.vertices = vertices;
        edge = new List<int>[vertices + 1];
        for (int i = 0; i <= vertices; i++) 
        {
            edge[i] = new List<int>();
        }
    }
    public void addEdge(int a, int b)
    {
        edge[a].Add(b);
    }
 
    public void dfs(int node, List<int> []adj, 
                    int []dp, Boolean []visited)
    {
        // Mark as visited
        visited[node] = true;
 
        // Traverse for all its children
        for (int i = 0; i < adj[node].Count; i++) 
        {
 
            // If not visited
            if (!visited[adj[node][i]])
                dfs(adj[node][i], adj, dp, visited);
 
            // Store the max of the paths
            dp[node] = Math.Max(dp[node], 1 +
                                dp[adj[node][i]]);
        }
    }
     
    // Function that returns the longest path
    public int findLongestPath( int n)
    {
        List<int> []adj = edge;
        // Dp array
        int[] dp = new int[n + 1];
 
        // Visited array to know if the node
        // has been visited previously or not
        Boolean[] visited = new Boolean[n + 1];
 
        // Call DFS for every unvisited vertex
        for (int i = 1; i <= n; i++) 
        {
            if (!visited[i])
                dfs(i, adj, dp, visited);
        }
 
        int ans = 0;
 
        // Traverse and find the maximum of all dp[i]
        for (int i = 1; i <= n; i++) 
        {
            ans = Math.Max(ans, dp[i]);
        }
        return ans;
    }
}
 
class GFG
{
    // Driver code
    public static void Main(String[] args)
    {
        int n = 5;
        Graph graph = new Graph(n);
        // Example-1
        graph.addEdge( 1, 2);
        graph.addEdge( 1, 3);
        graph.addEdge( 3, 2);
        graph.addEdge( 2, 4);
        graph.addEdge( 3, 4);
        graph.findLongestPath(n);
        Console.WriteLine(graph.findLongestPath(n));
    }
}
 
// This code is contributed by Princi Singh






 

 
 










<script>
 
// JavaScript program to find the longest
// path in the DAG
 
// Function to traverse the DAG
// and apply Dynamic Programming
// to find the longest path
function dfs(node, adj, dp, vis)
{
    // Mark as visited
    vis[node] = true;
 
    // Traverse for all its children
    for (var i = 0; i < adj[node].length; i++) {
 
        // If not visited
        if (!vis[adj[node][i]])
            dfs(adj[node][i], adj, dp, vis);
 
        // Store the max of the paths
        dp[node] = Math.max(dp[node], 1 + dp[adj[node][i]]);
    }
}
 
// Function to add an edge
function addEdge(adj, u, v)
{
    adj[u].push(v);
}
 
// Function that returns the longest path
function findLongestPath(adj, n)
{
    // Dp array
    var dp = Array(n+1).fill(0);
 
    // Visited array to know if the node
    // has been visited previously or not
    var vis = Array(n+1).fill(false);
 
    // Call DFS for every unvisited vertex
    for (var i = 1; i <= n; i++) {
        if (!vis[i])
            dfs(i, adj, dp, vis);
    }
 
    var ans = 0;
 
    // Traverse and find the maximum of all dp[i]
    for (var i = 1; i <= n; i++) {
        ans = Math.max(ans, dp[i]);
    }
    return ans;
}
 
// Driver Code
var n = 5;
var adj = Array.from(Array(n+1), ()=>Array());
// Example-1
addEdge(adj, 1, 2);
addEdge(adj, 1, 3);
addEdge(adj, 3, 2);
addEdge(adj, 2, 4);
addEdge(adj, 3, 4);
document.write( findLongestPath(adj, n));
 
</script>






3
 
Time Complexity: O(N+M) Auxiliary Space: O(N)  
YouTubeGeeksforGeeks500K subscribersLongest path in a Directed Acyclic graph | Dynamic Programming | GeeksforGeeksWatch laterShareCopy linkInfoShoppingTap to unmuteIf playback doesn't begin shortly, try restarting your device.You're signed outVideos you watch may be added to the TV's watch history and influence TV recommendations. To avoid this, cancel and sign in to YouTube on your computer.CancelConfirmMore videosMore videosSwitch cameraShareInclude playlistAn error occurred while retrieving sharing information. Please try again later.Watch on0:000:000:00 / 11:31•Live•<div class="player-unavailable"><h1 class="message">An error occurred.</h1><div class="submessage"><a href="https://www.youtube.com/watch?v=YxF-x3imVFA" target="_blank">Try watching this video on www.youtube.com</a>, or enable JavaScript if it is disabled in your browser.</div></div>
?list=PLqM7alHXFySEaZgcg7uRYJFBnYMLti-nh 
rituraj_jain
SumanSaurav
princi singh
rutvik_56
manishkumarsh120

DFS


Dynamic Programming


Graph

Writing code in comment? 
                                    Please use ide.geeksforgeeks.org, 
                                    generate link and share the link here.
                                
Bellman–Ford Algorithm | DP-23
Floyd Warshall Algorithm | DP-16
Matrix Chain Multiplication | DP-8
Travelling Salesman Problem | Set 1 (Naive and Dynamic Programming)
Sieve of Eratosthenes
Breadth First Search or BFS for a Graph
Depth First Search or DFS for a Graph
Graph and its representations
Bellman–Ford Algorithm | DP-23
Floyd Warshall Algorithm | DP-16