Open In App

# Find whether it is possible to finish all tasks or not from given dependencies

There are a total of n tasks you have to pick, labelled from 0 to n-1. Some tasks may have prerequisites, for example to pick task 0 you have to first pick task 1, which is expressed as a pair: [0, 1]
Given the total number of tasks and a list of prerequisite pairs, is it possible for you to finish all tasks?

Examples:

Input: 2, [[1, 0]]
Output: true
Explanation: There are a total of 2 tasks to pick. To pick task 1 you should have finished task 0. So it is possible.

Input: 2, [[1, 0], [0, 1]]
Output: false
Explanation: There are a total of 2 tasks to pick. To pick task 1 you should have finished task 0, and to pick task 0 you should also have finished task 1. So it is impossible.

Input: 3, [[1, 0], [2, 1], [3, 2]]
Output: true
Explanation: There are a total of 3 tasks to pick. To pick tasks 1 you should have finished task 0, and to pick task 2 you should have finished task 1 and to pick task 3 you should have finished task 2. So it is possible.

Recommended Practice

Solution:

We can consider this problem as a graph (related to topological sorting) problem. All tasks are nodes of the graph and if task u is a prerequisite of task v, we will add a directed edge from node u to node v. Now, this problem is equivalent to detecting a cycle in the graph represented by prerequisites. If there is a cycle in the graph, then it is not possible to finish all tasks (because in that case there is no any topological order of tasks). Both BFS and DFS can be used to solve it.

Since pair is inconvenient for the implementation of graph algorithms, we first transform it to a graph. If task u is a prerequisite of task v, we will add a directed edge from node u to node v.

Prerequisite: Detect Cycle in a Directed Graph

Using DFS For DFS, it will first visit a node, then one neighbor of it, then one neighbor of this neighbor… and so on. If it meets a node which was visited in the current process of DFS visit, a cycle is detected and we will return false. Otherwise it will start from another unvisited node and repeat this process till all the nodes have been visited. Note that you should make two records: one is to record all the visited nodes and the other is to record the visited nodes in the current DFS visit.

The code is as follows. We use a vector visited to record all the visited nodes and another vector onpath to record the visited nodes of the current DFS visit. Once the current visit is finished, we reset the onpath value of the starting node to false.

Implementation:

## CPP

 `// CPP program to check whether we can finish all``// tasks or not from given dependencies.``#include ``using` `namespace` `std;` `// Returns adjacency list representation from a list``// of pairs.``vector > make_graph(``int` `numTasks,``            ``vector >& prerequisites)``{``    ``vector > graph(numTasks);``    ``for` `(``auto` `pre : prerequisites)``        ``graph[pre.second].insert(pre.first);``    ``return` `graph;``}` `// A DFS based function to check if there is a cycle``// in the directed graph.``bool` `dfs_cycle(vector >& graph, ``int` `node,``               ``vector<``bool``>& onpath, vector<``bool``>& visited)``{``    ``if` `(visited[node])``        ``return` `false``;``    ``onpath[node] = visited[node] = ``true``;``    ``for` `(``int` `neigh : graph[node])``        ``if` `(onpath[neigh] || dfs_cycle(graph, neigh, onpath, visited))``            ``return` `true``;``    ``return` `onpath[node] = ``false``;``}` `// Main function to check whether possible to finish all tasks or not``bool` `canFinish(``int` `numTasks, vector >& prerequisites)``{``    ``vector > graph = make_graph(numTasks, prerequisites);``    ``vector<``bool``> onpath(numTasks, ``false``), visited(numTasks, ``false``);``    ``for` `(``int` `i = 0; i < numTasks; i++)``        ``if` `(!visited[i] && dfs_cycle(graph, i, onpath, visited))``            ``return` `false``;``    ``return` `true``;``}` `int` `main()``{``    ``int` `numTasks = 4;` `    ``vector > prerequisites;` `    ``// for prerequisites: [[1, 0], [2, 1], [3, 2]]` `    ``prerequisites.push_back(make_pair(1, 0));``    ``prerequisites.push_back(make_pair(2, 1));``    ``prerequisites.push_back(make_pair(3, 2));``    ``if` `(canFinish(numTasks, prerequisites)) {``        ``cout << ``"Possible to finish all tasks"``;``    ``}``    ``else` `{``        ``cout << ``"Impossible to finish all tasks"``;``    ``}` `    ``return` `0;``}`

## Java

 `// Java program to check whether we can finish all``// tasks or not from given dependencies.``import` `java.util.*;` `public` `class` `GFG{``    ` `    ``// class to store dependencies as a pair``    ``static` `class` `pair{``        ``int` `first, second;``        ` `        ``pair(``int` `first, ``int` `second){``            ``this``.first = first;``            ``this``.second = second;``        ``}``    ``}``    ` `    ``// Returns adjacency list representation from a list``    ``// of pairs.``    ``static` `ArrayList> make_graph(``int` `numTasks,``                ``Vector prerequisites)``    ``{``        ``ArrayList> graph = ``new` `ArrayList>(numTasks);` `        ``for``(``int` `i=``0``; i());``        ``}` `        ``for` `(pair pre : prerequisites)``            ``graph.get(pre.second).add(pre.first);` `        ``return` `graph;``    ``}``    ` `    ``// A DFS based function to check if there is a cycle``    ``// in the directed graph.``    ``static` `boolean` `dfs_cycle(ArrayList> graph, ``int` `node,``                ``boolean` `onpath[], ``boolean` `visited[])``    ``{``        ``if` `(visited[node])``            ``return` `false``;``        ``onpath[node] = visited[node] = ``true``;` `        ``for` `(``int` `neigh : graph.get(node))``            ``if` `(onpath[neigh] || dfs_cycle(graph, neigh, onpath, visited))``                ``return` `true``;` `        ``return` `onpath[node] = ``false``;``    ``}``    ` `    ``// Main function to check whether possible to finish all tasks or not``    ``static` `boolean` `canFinish(``int` `numTasks, Vector prerequisites)``    ``{``        ``ArrayList> graph = make_graph(numTasks, prerequisites);``        ` `        ``boolean` `onpath[] = ``new` `boolean``[numTasks];``        ``boolean` `visited[] = ``new` `boolean``[numTasks];` `        ``for` `(``int` `i = ``0``; i < numTasks; i++)``            ``if` `(!visited[i] && dfs_cycle(graph, i, onpath, visited))``                ``return` `false``;` `        ``return` `true``;``    ``}``    ` `    ``public` `static` `void` `main(String args[])``    ``{``        ``int` `numTasks = ``4``;``    ` `        ``Vector prerequisites = ``new` `Vector();;``    ` `        ``// for prerequisites: [[1, 0], [2, 1], [3, 2]]``    ` `        ``prerequisites.add(``new` `pair(``1``, ``0``));``        ``prerequisites.add(``new` `pair(``2``, ``1``));``        ``prerequisites.add(``new` `pair(``3``, ``2``));``        ` `        ``if` `(canFinish(numTasks, prerequisites)) {``            ``System.out.println(``"Possible to finish all tasks"``);``        ``}``        ``else` `{``            ``System.out.println(``"Impossible to finish all tasks"``);``        ``}``    ``}``}` `// This code is contributed by adityapande88.`

## Python3

 `# Python3 program to check whether we can finish all``# tasks or not from given dependencies.` `# class to store dependencies as a pair``class` `pair:``    ``def` `__init__(``self``, first, second):``        ``self``.first ``=` `first``        ``self``.second ``=` `second` `# Returns adjacency list representation from a list``# of pairs.``def` `make_graph(numTasks, prerequisites):``    ``graph ``=` `[]``    ``for` `i ``in` `range``(numTasks):``        ``graph.append([])` `    ``for` `pre ``in` `prerequisites:``        ``graph[pre.second].append(pre.first)` `    ``return` `graph` `# A DFS based function to check if there is a cycle``# in the directed graph.``def` `dfs_cycle(graph, node, onpath, visited):``    ``if` `visited[node]:``        ``return` `false``    ``onpath[node] ``=` `visited[node] ``=` `True``    ``for` `neigh ``in` `graph[node]:``        ``if` `(onpath[neigh] ``or` `dfs_cycle(graph, neigh, onpath, visited)):``            ``return` `true``    ``return` `False` `# Main function to check whether possible to finish all``# tasks or not``def` `canFinish(numTasks, prerequisites):``    ``graph ``=` `make_graph(numTasks, prerequisites)``    ``onpath ``=` `[``False``]``*``numTasks``    ``visited ``=` `[``False``]``*``numTasks``    ``for` `i ``in` `range``(numTasks):``        ``if` `(``not` `visited[i] ``and` `dfs_cycle(graph, i, onpath, visited)):``            ``return` `False``    ``return` `True`  `# Driver code to test above functions``numTasks ``=` `4``prerequisites ``=` `[]` `prerequisites.append(pair(``1``, ``0``))``prerequisites.append(pair(``2``, ``1``))``prerequisites.append(pair(``3``, ``2``))` `if` `canFinish(numTasks, prerequisites):``    ``print``(``"Possible to finish all tasks"``)``else``:``    ``print``(``"Impossible to finish all tasks"``)` `# This code is contributed by Abhijeet Kumar(abhijeet19403)`

## C#

 `// C# program to check whether we can finish all``// tasks or not from given dependencies.``using` `System;``using` `System.Collections.Generic;` `public` `class` `GFG {` `    ``// class to store dependencies as a pair``    ``public` `class` `pair {``        ``public` `int` `first, second;``        ``public` `pair(``int` `first, ``int` `second)``        ``{``            ``this``.first = first;``            ``this``.second = second;``        ``}``    ``}` `    ``// Returns adjacency list representation from a list``    ``// of pairs.``    ``static` `List >``    ``make_graph(``int` `numTasks, List prerequisites)``    ``{``        ``List > graph``            ``= ``new` `List >(numTasks);` `        ``for` `(``int` `i = 0; i < numTasks; i++) {``            ``graph.Add(``new` `List<``int``>());``        ``}` `        ``foreach``(pair pre ``in` `prerequisites) graph[pre.second]``            ``.Add(pre.first);` `        ``return` `graph;``    ``}` `    ``// A DFS based function to check if there is a cycle``    ``// in the directed graph.``    ``static` `bool` `dfs_cycle(List > graph, ``int` `node,``                          ``bool``[] onpath, ``bool``[] visited)``    ``{``        ``if` `(visited[node])``            ``return` `false``;``        ``onpath[node] = visited[node] = ``true``;` `        ``foreach``( ``int` `neigh ``in` `graph[node])``          ``if` `(onpath[neigh] || dfs_cycle(graph, neigh, onpath,``                                     ``visited))``            ``return` `true``;``        ``//onpath[node] = false;``        ``return` `false``;``    ``}` `    ``// Main function to check whether possible to finish all``    ``// tasks or not``    ``static` `bool` `canFinish(``int` `numTasks,``                          ``List prerequisites)``    ``{``        ``List > graph``            ``= make_graph(numTasks, prerequisites);` `        ``bool``[] onpath = ``new` `bool``[numTasks];``        ``bool``[] visited = ``new` `bool``[numTasks];` `        ``for` `(``int` `i = 0; i < numTasks; i++)``            ``if` `(!visited[i]``                ``&& dfs_cycle(graph, i, onpath, visited))``                ``return` `false``;` `        ``return` `true``;``    ``}` `    ``public` `static` `void` `Main(String[] args)``    ``{``        ``int` `numTasks = 4;` `        ``List prerequisites = ``new` `List();``        ``;` `        ``// for prerequisites: [[1, 0], [2, 1], [3, 2]]` `        ``prerequisites.Add(``new` `pair(1, 0));``        ``prerequisites.Add(``new` `pair(2, 1));``        ``prerequisites.Add(``new` `pair(3, 2));` `        ``if` `(canFinish(numTasks, prerequisites)) {``            ``Console.WriteLine(``                ``"Possible to finish all tasks"``);``        ``}``        ``else` `{``            ``Console.WriteLine(``                ``"Impossible to finish all tasks"``);``        ``}``    ``}``}` `// This code is contributed by Abhijeet Kumar(abhijeet19403)`

## Javascript

 `// Javascript program to check whether we can finish all``// tasks or not from given dependencies.` `// Returns adjacency list representation from a list``// of pairs.``function` `make_graph(numTasks, prerequisites){``    ``let graph = [];``    ` `    ``for``(let i = 0; i < numTasks; i++){``        ``graph.push([]);``    ``}` `    ``for``(let i = 0; i < prerequisites.length; i++){``        ``graph[prerequisites[i]].push(prerequisites[i]);``    ``}` `    ``return` `graph;``}` `// A DFS based function to check if there is a cycle``// in the directed graph.``function` `dfs_cycle(graph, node, onpath, visited){``    ``if` `(visited[node])``        ``return` `false``;``    ``onpath[node] = visited[node] = ``true``;``    ` `    ``for``(let i = 0; i < graph[node].length; i++){``        ``let neigh = graph[node][i];``        ``if` `(onpath[neigh] == ``true` `|| dfs_cycle(graph, neigh, onpath, visited) == ``true``)``            ``return` `true``;``    ``}``    ``return` `false``;``}` `// Main function to check whether possible to finish all``// tasks or not``function` `canFinish(numTasks, prerequisites){``    ``let graph = make_graph(numTasks, prerequisites);``    ``let onpath = ``new` `Array(numTasks).fill(``false``);``    ``let visited = ``new` `Array(numTasks).fill(``false``);` `    ``for``(let i = 0; i < numTasks; i++){``        ``if``(visited[i] == ``false`  `&& dfs_cycle(graph, i, onpath, visited ) == ``true``){``            ``return` `false``;``        ``}``    ``}` `    ``return` `true``;``}`  `// Driver code to test above functions``let numTasks = 4;``let prerequisites = [];` `prerequisites.push([1, 0]);``prerequisites.push([2, 1]);``prerequisites.push([3, 2]);` `if``(canFinish(numTasks, prerequisites))``    ``console.log(``"Possible to finish all tasks"``);``else``    ``console.log(``"Impossible to finish all tasks"``);` `// This code is contributed by Nidhi goel`

Output

`Possible to finish all tasks`

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

Using BFS:

BFS can be used to solve it using the idea of topological sort. If topological sorting is possible, it means there is no cycle and it is possible to finish all the tasks.

BFS uses the indegrees of each node. We will first try to find a node with 0 indegree. If we fail to do so, there must be a cycle in the graph and we return false. Otherwise we have found one. We set its indegree to be -1 to prevent from visiting it again and reduce the indegrees of all its neighbors by 1. This process will be repeated for n (number of nodes) times. If we have not returned false, we will return true.

Implementation:

## C++

 `// A BFS based solution to check if we can finish``// all tasks or not. This solution is mainly based``// on Kahn's algorithm.``#include ``using` `namespace` `std;` `// Returns adjacency list representation from a list``// of pairs.``vector >``make_graph(``int` `numTasks,``           ``vector >& prerequisites)``{``    ``vector > graph(numTasks);``    ``for` `(``auto` `pre : prerequisites)``        ``graph[pre.second].insert(pre.first);``    ``return` `graph;``}` `// Finds in-degree of every vertex``vector<``int``>``compute_indegree(vector >& graph)``{``    ``vector<``int``> degrees(graph.size(), 0);``    ``for` `(``auto` `neighbors : graph)``        ``for` `(``int` `neigh : neighbors)``            ``degrees[neigh]++;``    ``return` `degrees;``}` `// Main function to check whether possible to finish all``// tasks or not``bool` `canFinish(``int` `numTasks,``               ``vector >& prerequisites)``{``    ``vector > graph``        ``= make_graph(numTasks, prerequisites);``    ``vector<``int``> degrees = compute_indegree(graph);``    ``for` `(``int` `i = 0; i < numTasks; i++) {``        ``int` `j = 0;``        ``for` `(; j < numTasks; j++)``            ``if` `(!degrees[j])``                ``break``;``        ``if` `(j == numTasks)``            ``return` `false``;``        ``degrees[j] = -1;``        ``for` `(``int` `neigh : graph[j])``            ``degrees[neigh]--;``    ``}``    ``return` `true``;``}` `int` `main()``{``    ``int` `numTasks = 4;``    ``vector > prerequisites;``    ``prerequisites.push_back(make_pair(1, 0));``    ``prerequisites.push_back(make_pair(2, 1));``    ``prerequisites.push_back(make_pair(3, 2));``    ``if` `(canFinish(numTasks, prerequisites)) {``        ``cout << ``"Possible to finish all tasks"``;``    ``}``    ``else` `{``        ``cout << ``"Impossible to finish all tasks"``;``    ``}` `    ``return` `0;``}`

## Java

 `// A BFS based solution to check if we can finish``// all tasks or not. This solution is mainly based``// on Kahn's algorithm.``import` `java.util.*;` `public` `class` `GFG {` `    ``// class to store dependencies as a pair``    ``static` `class` `pair {``        ``int` `first, second;` `        ``pair(``int` `first, ``int` `second)``        ``{``            ``this``.first = first;``            ``this``.second = second;``        ``}``    ``}` `    ``// Returns adjacency list representation from a list``    ``// of pairs.``    ``static` `ArrayList >``    ``make_graph(``int` `numTasks, Vector prerequisites)``    ``{``        ``ArrayList > graph``            ``= ``new` `ArrayList >(numTasks);` `        ``for` `(``int` `i = ``0``; i < numTasks; i++) {``            ``graph.add(``new` `ArrayList());``        ``}` `        ``for` `(pair pre : prerequisites)``            ``graph.get(pre.second).add(pre.first);` `        ``return` `graph;``    ``}` `    ``// Finds in-degree of every vertex``    ``static` `int``[] compute_indegree(``        ``ArrayList > graph)``    ``{``        ``int` `degrees[] = ``new` `int``[graph.size()];` `        ``for` `(ArrayList neighbors : graph)``            ``for` `(``int` `neigh : neighbors)``                ``degrees[neigh]++;` `        ``return` `degrees;``    ``}` `    ``// Main function to check whether possible to finish all``    ``// tasks or not``    ``static` `boolean` `canFinish(``int` `numTasks,``                             ``Vector prerequisites)``    ``{``        ``ArrayList > graph``            ``= make_graph(numTasks, prerequisites);``        ``int` `degrees[] = compute_indegree(graph);` `        ``for` `(``int` `i = ``0``; i < numTasks; i++) {``            ``int` `j = ``0``;``            ``for` `(; j < numTasks; j++)``                ``if` `(degrees[j] == ``0``)``                    ``break``;` `            ``if` `(j == numTasks)``                ``return` `false``;` `            ``degrees[j] = -``1``;``            ``for` `(``int` `neigh : graph.get(j))``                ``degrees[neigh]--;``        ``}` `        ``return` `true``;``    ``}` `    ``public` `static` `void` `main(String args[])``    ``{``        ``int` `numTasks = ``4``;``        ``Vector prerequisites = ``new` `Vector();` `        ``prerequisites.add(``new` `pair(``1``, ``0``));``        ``prerequisites.add(``new` `pair(``2``, ``1``));``        ``prerequisites.add(``new` `pair(``3``, ``2``));` `        ``if` `(canFinish(numTasks, prerequisites)) {``            ``System.out.println(``                ``"Possible to finish all tasks"``);``        ``}``        ``else` `{``            ``System.out.println(``                ``"Impossible to finish all tasks"``);``        ``}``    ``}``}` `// This code is contributed by adityapande88.`

## Python3

 `# A BFS based solution to check if we can finish``# all tasks or not. This solution is mainly based``# on Kahn's algorithm.` `# class to store dependencies as a pair`  `class` `pair:``    ``def` `__init__(``self``, first, second):``        ``self``.first ``=` `first``        ``self``.second ``=` `second` `# Returns adjacency list representation from a list``# of pairs.`  `def` `make_graph(numTasks, prerequisites):``    ``graph ``=` `[]``    ``for` `i ``in` `range``(numTasks):``        ``graph.append([])` `    ``for` `pre ``in` `prerequisites:``        ``graph[pre.second].append(pre.first)` `    ``return` `graph`  `# Finds in-degree of every vertex``def` `compute_indegree(graph):``    ``degrees ``=` `[``0``]``*``len``(graph)` `    ``for` `neighbors ``in` `graph:``        ``for` `neigh ``in` `neighbors:``            ``degrees[neigh] ``+``=` `1` `    ``return` `degrees`  `# Main function to check whether possible to finish all tasks or not``def` `canFinish(numTasks, prerequisites):``    ``graph ``=` `make_graph(numTasks, prerequisites)``    ``degrees ``=` `compute_indegree(graph)` `    ``for` `i ``in` `range``(numTasks):``        ``j ``=` `0``        ``while``(j < numTasks):``            ``if` `(degrees[j] ``=``=` `0``):``                ``break``            ``j ``+``=` `1` `        ``if` `(j ``=``=` `numTasks):``            ``return` `False` `        ``degrees[j] ``=` `-``1``        ``for` `neigh ``in` `graph[j]:``            ``degrees[neigh] ``-``=` `1` `    ``return` `True` `numTasks ``=` `4``prerequisites ``=` `[]` `prerequisites.append(pair(``1``, ``0``))``prerequisites.append(pair(``2``, ``1``))``prerequisites.append(pair(``3``, ``2``))` `if` `(canFinish(numTasks, prerequisites)):``    ``print``(``"Possible to finish all tasks"``)``else``:``    ``print``(``"Impossible to finish all tasks"``)` `# This code is contributed by Lovely Jain`

## C#

 `// A BFS based solution to check if we can finish``// all tasks or not. This solution is mainly based``// on Kahn's algorithm.``using` `System;``using` `System.Collections.Generic;` `public` `class` `GFG {` `    ``// class to store dependencies as a pair``    ``public` `class` `pair {``        ``public` `int` `first, second;` `        ``public` `pair(``int` `first, ``int` `second)``        ``{``            ``this``.first = first;``            ``this``.second = second;``        ``}``    ``}` `    ``// Returns adjacency list representation from a list``    ``// of pairs.``    ``static` `List >``    ``make_graph(``int` `numTasks, List prerequisites)``    ``{``        ``List > graph``            ``= ``new` `List >(numTasks);` `        ``for` `(``int` `i = 0; i < numTasks; i++) {``            ``graph.Add(``new` `List<``int``>());``        ``}` `        ``foreach``(pair pre ``in` `prerequisites)``            ``graph[pre.second].Add(pre.first);` `        ``return` `graph;``    ``}` `    ``// Finds in-degree of every vertex``    ``static` `int``[] compute_indegree(``        ``List > graph)``    ``{``        ``int``[] degrees = ``new` `int``[graph.Count];` `        ``foreach``(List<``int``> neighbors ``in` `graph)``            ``foreach``(``int` `neigh ``in` `neighbors)``                ``degrees[neigh]++;` `        ``return` `degrees;``    ``}` `    ``// Main function to check whether possible to finish all``    ``// tasks or not``    ``static` `bool` `canFinish(``int` `numTasks,``                             ``List prerequisites)``    ``{``        ``List > graph``            ``= make_graph(numTasks, prerequisites);``        ``int``[] degrees = compute_indegree(graph);` `        ``for` `(``int` `i = 0; i < numTasks; i++) {``            ``int` `j = 0;``            ``for` `(; j < numTasks; j++)``                ``if` `(degrees[j] == 0)``                    ``break``;` `            ``if` `(j == numTasks)``                ``return` `false``;` `            ``degrees[j] = -1;``            ``foreach``(``int` `neigh ``in` `graph[j])``                ``degrees[neigh]--;``        ``}` `        ``return` `true``;``    ``}` `    ``public` `static` `void` `Main(String[] args)``    ``{``        ``int` `numTasks = 4;``        ``List prerequisites = ``new` `List();` `        ``prerequisites.Add(``new` `pair(1, 0));``        ``prerequisites.Add(``new` `pair(2, 1));``        ``prerequisites.Add(``new` `pair(3, 2));` `        ``if` `(canFinish(numTasks, prerequisites)) {``           ``Console.WriteLine(``                ``"Possible to finish all tasks"``);``        ``}``        ``else` `{``            ``Console.WriteLine(``                ``"Impossible to finish all tasks"``);``        ``}``    ``}``}` `// This code is contributed by Abhijeet Kumar(abhijeet19403)`

## Javascript

 ``

Output

`Possible to finish all tasks`

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