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 pathvoid 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 edgevoid addEdge(vector<int> adj[], int u, int v){    adj[u].push_back(v);} // Function that returns the longest pathint 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 Codeint 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 classclass 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 pathdef 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 edgedef addEdge(adj, u, v):      adj[u].append(v)   # Function that returns the longest pathdef 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 Codeif __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 DAGusing System;using System.Collections.Generic; // graph classclass 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 pathfunction 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 edgefunction addEdge(adj, u, v){    adj[u].push(v);} // Function that returns the longest pathfunction 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 Codevar n = 5;var adj = Array.from(Array(n+1), ()=>Array());// Example-1addEdge(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
Dynamic Programming
DFS
Graph
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
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
Detect Cycle in a Directed Graph
Bellman–Ford Algorithm | DP-23