Print all possible paths in a DAG from vertex whose indegree is 0

• Last Updated : 13 Oct, 2021

Given a Directed Acyclic Graph (DAG), having N vertices and M edges, The task is to print all path starting from vertex whose in-degree is zero.

Indegree of a vertex is the total number of incoming edges to a vertex.

Example:

Input: N = 6, edges[] = {{5, 0}, {5, 2}, {4, 0}, {4, 1}, {2, 3}, {3, 1}}
Output: All possible paths:
4 0
4 1
5 0
5 2 3 1
Explanation:
The given graph can be represented as:

There are two vertices whose indegree are zero i.e vertex 5 and 4, after exploring these vertices we got the fallowing path:
4 -> 0
4 -> 1
5 -> 0
5 -> 2 -> 3 -> 1

Input: N = 6, edges[] = {{0, 5}}
Output: All possible paths:
0 5
Explanation:
There will be only one possible path in the graph.

Approach:

1. Create a boolean array indeg0 which store a true value for all those vertex whose indegree is zero.
2. Apply DFS on all those vertex whose indegree is 0.
3. Print all path starting from a vertex whose indegree is 0 to a vertex whose outdegrees are zero.

Illustration:
For the above graph:
indeg0[] = {False, False, False, False, True, True}
Since indeg[4] = True, so applying DFS on vertex 4 and printing all path terminating to 0 outdegree vertex are as follow:
4 -> 0
4 -> 1
Also indeg[5] = True, so applying DFS on vertex 5 and printing all path terminating to 0 outdegree vertex are as follow:
5 -> 0
5 -> 2 -> 3 -> 1

Here is the implementation of the above approach:

C++

 `// C++ program to print``// all possible paths in a DAG` `#include ``using` `namespace` `std;` `vector<``int``> path;` `vector<``bool``> indeg0, outdeg0;` `vector > adj;` `vector<``bool``> visited;` `// Recursive function to print all paths``void` `dfs(``int` `s)``{``    ``// Append the node in path``    ``// and set visited``    ``path.push_back(s);``    ``visited[s] = ``true``;` `    ``//  Path started with a node``    ``//  having in-degree 0 and``    ``//  current node has out-degree 0,``    ``//  print current path``    ``if` `(outdeg0[s] && indeg0[path[0]]) {``        ``for` `(``auto` `x : path)``            ``cout << x << ``" "``;``        ``cout << ``'\n'``;``    ``}` `    ``for` `(``auto` `node : adj[s]) {``        ``if` `(!visited[node])``            ``dfs(node);``    ``}` `    ``path.pop_back();``    ``visited[s] = ``false``;``}` `void` `print_all_paths(``int` `n)``{``    ``for` `(``int` `i = 0; i < n; i++) {``        ``// for each node with in-degree 0``        ``// print all possible paths``        ``if` `(indeg0[i] && !adj[i].empty()) {``            ``dfs(i);``        ``}``    ``}``}` `// Driver Code``int` `main()``{``    ``int` `n;``    ``n = 6;` `    ``// set all nodes unvisited``    ``visited = vector<``bool``>(n, ``false``);` `    ``// adjacency list for nodes``    ``adj = vector >(n);` `    ``// indeg0 and outdeg0 arrays``    ``indeg0 = vector<``bool``>(n, ``true``);``    ``outdeg0 = vector<``bool``>(n, ``true``);` `    ``// edges``    ``vector > edges``        ``= { { 5, 0 }, { 5, 2 }, { 2, 3 },``            ``{ 4, 0 }, { 4, 1 }, { 3, 1 } };` `    ``for` `(``int` `i = 0; i < edges.size(); i++) {``        ``int` `u = edges[i].first;``        ``int` `v = edges[i].second;` `        ``adj[u].push_back(v);` `        ``// set indeg0[v] <- false``        ``indeg0[v] = ``false``;` `        ``// set outdeg0[u] <- false``        ``outdeg0[u] = ``false``;``    ``}``    ``cout << ``"All possible paths:\n"``;``    ``print_all_paths(n);``    ``return` `0;``}`

Python3

 `# Python program to print all``# possible paths in a DAG` `# Recursive function to print all paths``def` `dfs(s):``    ``# Append the node in path``    ``# and set visited``    ``path.append(s)``    ``visited[s] ``=` `True` `    ``# Path started with a node``    ``# having in-degree 0 and``    ``# current node has out-degree 0,``    ``# print current path``    ``if` `outdeg0[s] ``and` `indeg0[path[``0``]]:``        ``print``(``*``path)` `    ``# Recursive call to print all paths``    ``for` `node ``in` `adj[s]:``        ``if` `not` `visited[node]:``            ``dfs(node)` `    ``# Remove node from path``    ``# and set unvisited``    ``path.pop()``    ``visited[s] ``=` `False`  `def` `print_all_paths(n):``    ``for` `i ``in` `range``(n):` `        ``# for each node with in-degree 0``        ``# print all possible paths``        ``if` `indeg0[i] ``and` `adj[i]:``            ``path ``=` `[]``            ``visited ``=` `[``False``] ``*` `(n ``+` `1``)``            ``dfs(i)`  `# Driver code``from` `collections ``import` `defaultdict` `n ``=` `6``# set all nodes unvisited``visited ``=` `[``False``] ``*` `(n ``+` `1``)``path ``=` `[]` `# edges = (a, b): a -> b``edges ``=` `[(``5``, ``0``), (``5``, ``2``), (``2``, ``3``),``         ``(``4``, ``0``), (``4``, ``1``), (``3``, ``1``)]` `# adjacency list for nodes``adj ``=` `defaultdict(``list``)` `# indeg0 and outdeg0 arrays``indeg0 ``=` `[``True``]``*``n``outdeg0 ``=` `[``True``]``*``n` `for` `edge ``in` `edges:``    ``u, v ``=` `edge[``0``], edge[``1``]``    ``# u -> v``    ``adj[u].append(v)` `    ``# set indeg0[v] <- false``    ``indeg0[v] ``=` `False` `    ``# set outdeg0[u] <- false``    ``outdeg0[u] ``=` `False` `print``(``'All possible paths:'``)``print_all_paths(n)`

Output:

```All possible paths:
4 0
4 1
5 0
5 2 3 1```

Time Complexity: O (N + E)2
Auxiliary Space: O (N)

My Personal Notes arrow_drop_up