<p>Given a directed acyclic graph (<strong>DAG</strong>) of <code>n</code> nodes labeled from <code>0</code> to <code>n - 1</code>, find all possible paths from node <code>0</code> to node <code>n - 1</code> and return them in <strong>any order</strong>.</p>

<p>The graph is given as follows: <code>graph[i]</code> is a list of all nodes you can visit from node <code>i</code> (i.e., there is a directed edge from node <code>i</code> to node <code>graph[i][j]</code>).</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2020/09/28/all_1.jpg" style="width: 242px; height: 242px;" />
<pre>
<strong>Input:</strong> graph = [[1,2],[3],[3],[]]
<strong>Output:</strong> [[0,1,3],[0,2,3]]
<strong>Explanation:</strong> There are two paths: 0 -&gt; 1 -&gt; 3 and 0 -&gt; 2 -&gt; 3.
</pre>

<p><strong class="example">Example 2:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2020/09/28/all_2.jpg" style="width: 423px; height: 301px;" />
<pre>
<strong>Input:</strong> graph = [[4,3,1],[3,2,4],[3],[4],[]]
<strong>Output:</strong> [[0,4],[0,3,4],[0,1,3,4],[0,1,2,3,4],[0,1,4]]
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>n == graph.length</code></li>
	<li><code>2 &lt;= n &lt;= 15</code></li>
	<li><code>0 &lt;= graph[i][j] &lt; n</code></li>
	<li><code>graph[i][j] != i</code> (i.e., there will be no self-loops).</li>
	<li>All the elements of <code>graph[i]</code> are <strong>unique</strong>.</li>
	<li>The input graph is <strong>guaranteed</strong> to be a <strong>DAG</strong>.</li>
</ul>

class Solution {
public:
    void calculateIndgree(vector<vector<int>>& graph, vector<int>& indegree) {
        int vertices = graph.size();
        
        for (int i = 0; i < vertices; i++) {
            for (int nbr : graph[i]) {
                indegree[nbr]++;
            }
        }
    }

    vector<int> topologicalSort(vector<vector<int>>& graph, vector<int>& indegree) {
        int vertices = graph.size();
        std::queue<int> q;
        vector<int> ans;
        vector<bool> visited(vertices, false);
        for (int i = 0; i < vertices; i++) {
            if (indegree[i] == 0) {
                q.push(i);
            }
        }
        
        ans.push_back(q.front());
        
        while (!q.empty()) {
            int node = q.front();
            q.pop();
           
            //visited[node] = true;
            for (int nbr : graph[node]) {
                
                indegree[nbr]--;
                if (indegree[nbr] == 0) {
                    ans.push_back(nbr);
                    q.push(nbr);
                }
            }
        }
        return ans;
    }

    void printVal(vector<int>& tSort) {
        for (int i : tSort) {
            cout << i << "\t";
        }
        cout << "\n";
    }

    vector<vector<int>> allPathsSourceTarget(vector<vector<int>>& graph) {
        int vertices = graph.size();
        vector<int> indegree(vertices, 0);
        vector<vector<vector<int>>> paths(vertices);
        bool flag = false;
        
        calculateIndgree(graph, indegree);
        
        vector<int> tSort = topologicalSort(graph, indegree);
        
        //printVal(tSort);
        
        for (int i = tSort.size() - 1; i >= 0; i--) {
            if (tSort[i] == vertices - 1) {
                flag = true;
                vector<int> temp = {tSort[i]};
                paths[tSort[i]].push_back(temp);
                continue;
            }
            
            if (flag) {
                for (int nbr : graph[tSort[i]]) {
                    if (paths[nbr].size()) {
                        vector<int> temp = { tSort[i] };
                        for (vector<int> p : paths[nbr]) {
                            vector<int> t = temp;
                            for (int j : p) {
                                t.push_back(j);
                            }
                            paths[tSort[i]].push_back(t);
                        }
                    }
                }
            }
        }
        
        return paths[0];
    }
};
23416