Suppose we have n different tasks; these tasks are labeled from 0 to n-1. Some tasks may have prerequisites tasks, so as an example if we want to choose task 2 then we have to first finish the task 1, which is represented as a pair − [2, 1] If we have total number of tasks and a list of prerequisite pairs, we have to find the ordering of tasks to finish all tasks. If there are more than one correct order, we can just return one of them. And if it is impossible to finish all given tasks, return an empty array.
So, if the input is like n = 4, and A = [[1, 0], [2, 0], [3, 2], [3, 1],[4,2]], then the output will be [0, 2, 1, 4, 3]
To solve this, we will follow these steps −
Define a function dfs(), this will take graph, start, an onpath, an array visited, an array toposort,
if visited[start] is marked, then −
return false
onpath[start] := true, visited[start] := true
for each neighbor in graph[start], do
if onpath[neighbor] is true or dfs(graph, neighbor, onpath, visited, toposort) is true, then −
return true
insert start at the end of toposort
return onpath[start] := false
From the main method, do the following −
graph = create graph with n vertices and edges stored in pre array
Define an array toposort
Define an array onpath of size n and fill with false
Define an array visited of size n and fill with false
for initialize i := 0, when i < n, update (increase i by 1), do −
if visited[i] is false and dfs(graph, i, onpath, visited, toposort) is true, then −
return blank array
reverse the array toposort
return toposort
Example
Let us see the following implementation to get better understanding −
#include <bits/stdc++.h> using namespace std; vector<unordered_set<int> > create_graph(int n, vector<pair<int, int> >& pre) { vector<unordered_set<int> > graph(n); for (auto pre : pre) graph[pre.second].insert(pre.first); return graph; } bool dfs(vector<unordered_set<int> >& graph, int start,vector<bool>& onpath, vector<bool>& visited, vector<int>& toposort) { if (visited[start]) return false; onpath[start] = visited[start] = true; for (int neigh : graph[start]) if (onpath[neigh] || dfs(graph, neigh, onpath, visited, toposort)) return true; toposort.push_back(start); return onpath[start] = false; } vector<int> get_order(int n, vector<pair<int, int> > &pre){ vector<unordered_set<int> > graph = create_graph(n, pre); vector<int> toposort; vector<bool> onpath(n, false), visited(n, false); for (int i = 0; i < n; i++) if (!visited[i] && dfs(graph, i, onpath, visited, toposort)) return {}; reverse(toposort.begin(), toposort.end()); return toposort; } int main() { int n = 4; vector<pair<int, int> > pre = {{1, 0}, {2, 0}, {3, 2}, {3, 1},{4,0}}; vector<int> v = get_order(n, pre); for (int i = 0; i < v.size(); i++) { cout << v[i] << " "; } }
Input
4, {{1, 0}, {2, 0}, {3, 2}, {3, 1},{4,0}}
Output
0 1 4 2 3