Given a **Directed Acyclic Graph** having **V **vertices and** E **edges, where each edge **{U, V}** represents the Jobs **U** and **V** such that Job **V** can only be started only after completion of Job **U**. The task is to determine the minimum time taken by each job to be completed where each Job takes unit time to get completed.

**Examples:**

Input:N=10, E = 13, Below is the given graph:

Output:1 1 2 2 2 3 4 5 2 6Explanation:

Start the jobs 1 and 2 at the beginning and complete them at 1 unit of time.

Since, jobs 3, 4, 5, and 9 have the only dependency on one job (i.e 1st job for jobs 3, 4, and 5 and 2nd job for job 9). So, we can start these jobs at 1st unit of time and complete these at 2nd unit of time after the completion of the dependent Job.

Similarly,

Job 6 can only be done after 3rd and 4th jobs are done. So, start it at 2nd unit of time and complete it at 3rd unit of time.

Job 7 can only be done after job 6 is done. So, you can start it at 3rd unit of time and complete it at 4th unit of time.

Job 8 can only be done after 4th, 5th, and 7th jobs are done. So, start it at 4th unit of time and complete it at 5th unit of time.

Job 10 can only be done after the 8th job is done. So, start it at 5th unit of time and complete it at 6th unit of time.

Input:N = 7, E = 7, Below is the given graph:

Output:1 2 3 3 3 4 4Explanation:

Start the Job 1 at the beginning and complete it at 1st unit of time.

The job 2 can only be done after 1st Job is done. So, start it at 1st unit of time and complete it at 2nd unit of time.

Since, Job 3, 4, and 5 have the only dependency on 2nd Job. So, start these jobs at 2nd unit of time and complete these at 3rd unit of time.

The Job 6 can only be done after the 3rd and 4th Job is done. So, start it at 3rd unit of time and complete it at 4th unit of time.

The Job 7 can only be done after the 5th Job is done. So, start it at 3rd hour and complete it at 4th unit of time.

**Approach:** The job can be started only if all the jobs that are prerequisites of the job that are done. Therefore, the idea is to use Topological Sort for the given network. Below are the steps:

- Finish the jobs that are not dependent on any other job.
- Create an array
**inDegree[]**to store the count of the dependent node for each node in the given network. - Initialize a queue and push all the vertex whose
**inDegree[]**is 0. - Initialize the timer to 1 and store the current queue size(say
**size**) and do the following:- Pop the node from the queue until the size is
**0**and update the finishing time of this node to the**timer**. - While popping the node(say node
**U**) from the queue decrement the**inDegree**of every node connected to it. - If
**inDegree**of any node is**0**in the above step then insert that node in the queue. - Increment the timer after all the above steps.

- Pop the node from the queue until the size is
- Print the finishing time of all the nodes after we traverse every node in the above step.

Below is the implementation of the above approach:

## C++

`// C++ program for the above approach ` `#include <bits/stdc++.h> ` `using` `namespace` `std; ` `#define maxN 100000 ` ` ` `// Adjacency List to store the graph ` `vector<` `int` `> graph[maxN]; ` ` ` `// Array to store the in-degree of node ` `int` `indegree[maxN]; ` ` ` `// Array to store the time in which ` `// the job i can be done ` `int` `job[maxN]; ` ` ` `// Function to add directed edge ` `// between two vertices ` `void` `addEdge(` `int` `u, ` `int` `v) ` `{ ` ` ` `// Insert edge from u to v ` ` ` `graph[u].push_back(v); ` ` ` ` ` `// Increasing the indegree ` ` ` `// of vertex v ` ` ` `indegree[v]++; ` `} ` ` ` `// Function to find the minimum time ` `// needed by each node to get the task ` `void` `printOrder(` `int` `n, ` `int` `m) ` `{ ` ` ` `// Find the topo sort order ` ` ` `// using the indegree approach ` ` ` ` ` `// Queue to store the ` ` ` `// nodes while processing ` ` ` `queue<` `int` `> q; ` ` ` ` ` `// Pushing all the vertex in the ` ` ` `// queue whose in-degree is 0 ` ` ` ` ` `// Update the time of the jobs ` ` ` `// who don't require any job to ` ` ` `// be completed before this job ` ` ` `for` `(` `int` `i = 1; i <= n; i++) { ` ` ` `if` `(indegree[i] == 0) { ` ` ` `q.push(i); ` ` ` `job[i] = 1; ` ` ` `} ` ` ` `} ` ` ` ` ` `// Iterate until queue is empty ` ` ` `while` `(!q.empty()) { ` ` ` ` ` `// Get front element of queue ` ` ` `int` `cur = q.front(); ` ` ` ` ` `// Pop the front element ` ` ` `q.pop(); ` ` ` ` ` `for` `(` `int` `adj : graph[cur]) { ` ` ` ` ` `// Decrease in-degree of ` ` ` `// the current node ` ` ` `indegree[adj]--; ` ` ` ` ` `if` `(job[adj] < 1 + job[cur]) { ` ` ` ` ` `// Update the time ` ` ` `job[adj] = max(job[adj], ` ` ` `1 + job[cur]); ` ` ` `} ` ` ` ` ` `// Push its adjacent elements ` ` ` `if` `(indegree[adj] == 0) ` ` ` `q.push(adj); ` ` ` `} ` ` ` `} ` ` ` ` ` `// Print the time to complete ` ` ` `// the job ` ` ` `for` `(` `int` `i = 1; i <= n; i++) ` ` ` `cout << job[i] << ` `" "` `; ` ` ` `cout << ` `"\n"` `; ` `} ` ` ` `// Driver Code ` `int` `main() ` `{ ` ` ` `// Given Nodes N and edges M ` ` ` `int` `n, m; ` ` ` `n = 10; ` ` ` `m = 13; ` ` ` ` ` `// Given Directed Edges of graph ` ` ` `addEdge(1, 3); ` ` ` `addEdge(1, 4); ` ` ` `addEdge(1, 5); ` ` ` `addEdge(2, 3); ` ` ` `addEdge(2, 8); ` ` ` `addEdge(2, 9); ` ` ` `addEdge(3, 6); ` ` ` `addEdge(4, 6); ` ` ` `addEdge(4, 8); ` ` ` `addEdge(5, 8); ` ` ` `addEdge(6, 7); ` ` ` `addEdge(7, 8); ` ` ` `addEdge(8, 10); ` ` ` ` ` `// Function Call ` ` ` `printOrder(n, m); ` ` ` `return` `0; ` `} ` |

*chevron_right*

*filter_none*

## Java

`// Java program for the above approach ` `import` `java.util.*; ` ` ` `class` `GFG{ ` ` ` `static` `final` `int` `maxN = ` `100000` `; ` ` ` `// Adjacency List to store the graph ` `@SuppressWarnings` `(` `"unchecked"` `) ` `static` `Vector<Integer> []graph = ` `new` `Vector[maxN]; ` ` ` `// Array to store the in-degree of node ` `static` `int` `[]indegree = ` `new` `int` `[maxN]; ` ` ` `// Array to store the time in which ` `// the job i can be done ` `static` `int` `[]job = ` `new` `int` `[maxN]; ` ` ` `// Function to add directed edge ` `// between two vertices ` `static` `void` `addEdge(` `int` `u, ` `int` `v) ` `{ ` ` ` ` ` `// Insert edge from u to v ` ` ` `graph[u].add(v); ` ` ` ` ` `// Increasing the indegree ` ` ` `// of vertex v ` ` ` `indegree[v]++; ` `} ` ` ` `// Function to find the minimum time ` `// needed by each node to get the task ` `static` `void` `printOrder(` `int` `n, ` `int` `m) ` `{ ` ` ` ` ` `// Find the topo sort order ` ` ` `// using the indegree approach ` ` ` ` ` `// Queue to store the ` ` ` `// nodes while processing ` ` ` `Queue<Integer> q = ` `new` `LinkedList<>(); ` ` ` ` ` `// Pushing all the vertex in the ` ` ` `// queue whose in-degree is 0 ` ` ` ` ` `// Update the time of the jobs ` ` ` `// who don't require any job to ` ` ` `// be completed before this job ` ` ` `for` `(` `int` `i = ` `1` `; i <= n; i++) ` ` ` `{ ` ` ` `if` `(indegree[i] == ` `0` `) ` ` ` `{ ` ` ` `q.add(i); ` ` ` `job[i] = ` `1` `; ` ` ` `} ` ` ` `} ` ` ` ` ` `// Iterate until queue is empty ` ` ` `while` `(!q.isEmpty()) ` ` ` `{ ` ` ` ` ` `// Get front element of queue ` ` ` `int` `cur = q.peek(); ` ` ` ` ` `// Pop the front element ` ` ` `q.remove(); ` ` ` ` ` `for` `(` `int` `adj : graph[cur]) ` ` ` `{ ` ` ` ` ` `// Decrease in-degree of ` ` ` `// the current node ` ` ` `indegree[adj]--; ` ` ` ` ` `if` `(job[adj] < ` `1` `+ job[cur]) ` ` ` `{ ` ` ` ` ` `// Update the time ` ` ` `job[adj] = Math.max(job[adj], ` ` ` `1` `+ job[cur]); ` ` ` `} ` ` ` ` ` `// Push its adjacent elements ` ` ` `if` `(indegree[adj] == ` `0` `) ` ` ` `q.add(adj); ` ` ` `} ` ` ` `} ` ` ` ` ` `// Print the time to complete ` ` ` `// the job ` ` ` `for` `(` `int` `i = ` `1` `; i <= n; i++) ` ` ` `System.out.print(job[i] + ` `" "` `); ` ` ` `System.out.print(` `"\n"` `); ` `} ` ` ` `// Driver Code ` `public` `static` `void` `main(String[] args) ` `{ ` ` ` ` ` `// Given Nodes N and edges M ` ` ` `int` `n, m; ` ` ` `n = ` `10` `; ` ` ` `m = ` `13` `; ` ` ` ` ` `for` `(` `int` `i = ` `0` `; i < graph.length; i++) ` ` ` `graph[i] = ` `new` `Vector<Integer>(); ` ` ` ` ` `// Given directed edges of graph ` ` ` `addEdge(` `1` `, ` `3` `); ` ` ` `addEdge(` `1` `, ` `4` `); ` ` ` `addEdge(` `1` `, ` `5` `); ` ` ` `addEdge(` `2` `, ` `3` `); ` ` ` `addEdge(` `2` `, ` `8` `); ` ` ` `addEdge(` `2` `, ` `9` `); ` ` ` `addEdge(` `3` `, ` `6` `); ` ` ` `addEdge(` `4` `, ` `6` `); ` ` ` `addEdge(` `4` `, ` `8` `); ` ` ` `addEdge(` `5` `, ` `8` `); ` ` ` `addEdge(` `6` `, ` `7` `); ` ` ` `addEdge(` `7` `, ` `8` `); ` ` ` `addEdge(` `8` `, ` `10` `); ` ` ` ` ` `// Function call ` ` ` `printOrder(n, m); ` `} ` `} ` ` ` `// This code is contributed by Amit Katiyar ` |

*chevron_right*

*filter_none*

## C#

`// C# program for the above approach ` `using` `System; ` `using` `System.Collections.Generic; ` ` ` `class` `GFG{ ` ` ` `static` `readonly` `int` `maxN = 100000; ` ` ` `// Adjacency List to store the graph ` `static` `List<` `int` `> []graph = ` `new` `List<` `int` `>[maxN]; ` ` ` `// Array to store the in-degree of node ` `static` `int` `[]indegree = ` `new` `int` `[maxN]; ` ` ` `// Array to store the time in which ` `// the job i can be done ` `static` `int` `[]job = ` `new` `int` `[maxN]; ` ` ` `// Function to add directed edge ` `// between two vertices ` `static` `void` `addEdge(` `int` `u, ` `int` `v) ` `{ ` ` ` ` ` `// Insert edge from u to v ` ` ` `graph[u].Add(v); ` ` ` ` ` `// Increasing the indegree ` ` ` `// of vertex v ` ` ` `indegree[v]++; ` `} ` ` ` `// Function to find the minimum time ` `// needed by each node to get the task ` `static` `void` `printOrder(` `int` `n, ` `int` `m) ` `{ ` ` ` ` ` `// Find the topo sort order ` ` ` `// using the indegree approach ` ` ` ` ` `// Queue to store the ` ` ` `// nodes while processing ` ` ` `Queue<` `int` `> q = ` `new` `Queue<` `int` `>(); ` ` ` ` ` `// Pushing all the vertex in the ` ` ` `// queue whose in-degree is 0 ` ` ` ` ` `// Update the time of the jobs ` ` ` `// who don't require any job to ` ` ` `// be completed before this job ` ` ` `for` `(` `int` `i = 1; i <= n; i++) ` ` ` `{ ` ` ` `if` `(indegree[i] == 0) ` ` ` `{ ` ` ` `q.Enqueue(i); ` ` ` `job[i] = 1; ` ` ` `} ` ` ` `} ` ` ` ` ` `// Iterate until queue is empty ` ` ` `while` `(q.Count != 0) ` ` ` `{ ` ` ` ` ` `// Get front element of queue ` ` ` `int` `cur = q.Peek(); ` ` ` ` ` `// Pop the front element ` ` ` `q.Dequeue(); ` ` ` ` ` `foreach` `(` `int` `adj ` `in` `graph[cur]) ` ` ` `{ ` ` ` ` ` `// Decrease in-degree of ` ` ` `// the current node ` ` ` `indegree[adj]--; ` ` ` ` ` `if` `(job[adj] < 1 + job[cur]) ` ` ` `{ ` ` ` ` ` `// Update the time ` ` ` `job[adj] = Math.Max(job[adj], ` ` ` `1 + job[cur]); ` ` ` `} ` ` ` ` ` `// Push its adjacent elements ` ` ` `if` `(indegree[adj] == 0) ` ` ` `q.Enqueue(adj); ` ` ` `} ` ` ` `} ` ` ` ` ` `// Print the time to complete ` ` ` `// the job ` ` ` `for` `(` `int` `i = 1; i <= n; i++) ` ` ` `Console.Write(job[i] + ` `" "` `); ` ` ` ` ` `Console.Write(` `"\n"` `); ` `} ` ` ` `// Driver Code ` `public` `static` `void` `Main(String[] args) ` `{ ` ` ` ` ` `// Given Nodes N and edges M ` ` ` `int` `n, m; ` ` ` `n = 10; ` ` ` `m = 13; ` ` ` ` ` `for` `(` `int` `i = 0; i < graph.Length; i++) ` ` ` `graph[i] = ` `new` `List<` `int` `>(); ` ` ` ` ` `// Given directed edges of graph ` ` ` `addEdge(1, 3); ` ` ` `addEdge(1, 4); ` ` ` `addEdge(1, 5); ` ` ` `addEdge(2, 3); ` ` ` `addEdge(2, 8); ` ` ` `addEdge(2, 9); ` ` ` `addEdge(3, 6); ` ` ` `addEdge(4, 6); ` ` ` `addEdge(4, 8); ` ` ` `addEdge(5, 8); ` ` ` `addEdge(6, 7); ` ` ` `addEdge(7, 8); ` ` ` `addEdge(8, 10); ` ` ` ` ` `// Function call ` ` ` `printOrder(n, m); ` `} ` `} ` ` ` `// This code is contributed by Amit Katiyar ` |

*chevron_right*

*filter_none*

**Output:**

1 1 2 2 2 3 4 5 2 6

**Time Complexity:** O(V+E), where V is the number of nodes and E is the number of edges. **Auxiliary Space:** O(V)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the **DSA Self Paced Course** at a student-friendly price and become industry ready.

## Recommended Posts:

- Shortest Path in Directed Acyclic Graph
- Longest Path in a Directed Acyclic Graph
- Assign directions to edges so that the directed graph remains acyclic
- All Topological Sorts of a Directed Acyclic Graph
- Longest Path in a Directed Acyclic Graph | Set 2
- Clone a Directed Acyclic Graph
- Number of paths from source to destination in a directed acyclic graph
- Longest path in a directed Acyclic graph | Dynamic Programming
- Minimum number of edges required to be removed from an Undirected Graph to make it acyclic
- Maximize jobs that can be completed under given constraint
- Count permutations of all integers upto N that can form an acyclic graph based on given conditions
- Convert the undirected graph into directed graph such that there is no path of length greater than 1
- Convert undirected connected graph to strongly connected directed graph
- Find dependencies of each Vertex in a Directed Graph
- Print completed tasks at end according to Dependencies
- Minimum edges to be added in a directed graph so that any node can be reachable from a given node
- Minimum Cost Path in a directed graph via given set of intermediate nodes
- Calculate number of nodes between two vertices in an acyclic Graph by Disjoint Union method
- DFS for a n-ary tree (acyclic graph) represented as adjacency list
- Count ways to change direction of edges such that graph becomes acyclic

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.