/* Graph edges: 0 -> 1 0 -> 2 1 -> 3 2 -> 3 */ #include <iostream> #include <vector> #include <stack> using namespace std; void dfs(int node, vector<vector<int>>& adj, vector<bool>& visited, stack<int>& st) { visited[node] = true; for (int nbr : adj[node]) { if (!visited[nbr]) { dfs(nbr, adj, visited, st); } } st.push(node); } int main() { int V = 4; vector<vector<int>> adj(V); adj[0] = {1, 2}; adj[1] = {3}; adj[2] = {3}; vector<bool> visited(V, false); stack<int> st; for (int i = 0; i < V; i++) { if (!visited[i]) { dfs(i, adj, visited, st); } } while (!st.empty()) { cout << st.top() << " "; st.pop(); } return 0; }
The DFS visits node 0 first, then explores node 1 and node 2. Both 1 and 2 lead to 3. The stack pushes nodes after visiting all their neighbors, so 3 is pushed first, then 1 and 2, and finally 0. The output is the reverse of the finishing times: 0 2 1 3.
#include <iostream> #include <vector> #include <stack> using namespace std; void dfs(int node, vector<vector<int>>& adj, vector<bool>& visited, stack<int>& st) { visited[node] = true; for (int nbr : adj[node]) { if (!visited[nbr]) { dfs(nbr, adj, visited, st); } } st.push(node); } int main() { int V = 6; vector<vector<int>> adj(V); adj[5] = {2, 0}; adj[4] = {0, 1}; adj[2] = {3}; adj[3] = {1}; vector<bool> visited(V, false); stack<int> st; for (int i = 0; i < V; i++) { if (!visited[i]) { dfs(i, adj, visited, st); } } while (!st.empty()) { cout << st.top() << " "; st.pop(); } return 0; }
DFS visits node 0,1,2,3 only after visiting 4 and 5. Node 4 and 5 have no incoming edges, so they are visited first. The stack pushes nodes after all descendants are visited, resulting in the order 4 5 2 3 1 0.
#include <iostream> #include <vector> #include <stack> using namespace std; void dfs(int node, vector<vector<int>>& adj, vector<bool>& visited, stack<int>& st) { visited[node] = true; for (int nbr : adj[node]) { if (visited[nbr]) { dfs(nbr, adj, visited, st); } } st.push(node); } int main() { int V = 3; vector<vector<int>> adj(V); adj[0] = {1}; adj[1] = {2}; vector<bool> visited(V, false); stack<int> st; for (int i = 0; i < V; i++) { if (!visited[i]) { dfs(i, adj, visited, st); } } while (!st.empty()) { cout << st.top() << " "; st.pop(); } return 0; }
The bug is that the code recurses only if the neighbor is already visited, which is wrong. It should recurse only if the neighbor is not visited to explore all nodes properly.
#include <iostream> #include <vector> #include <stack> using namespace std; void dfs(int node, vector<vector<int>>& adj, vector<bool>& visited, stack<int>& st) { visited[node] = true; for (int nbr : adj[node]) { if (!visited[nbr]) { dfs(nbr, adj, visited, st); } } st.push(node); } int main() { int V = 3; vector<vector<int>> adj(V); adj[0] = {1}; adj[1] = {2}; adj[2] = {0}; // cycle here vector<bool> visited(V, false); stack<int> st; for (int i = 0; i < V; i++) { if (!visited[i]) { dfs(i, adj, visited, st); } } while (!st.empty()) { cout << st.top() << " "; st.pop(); } return 0; }
The code does not detect cycles, so it runs and outputs nodes in some order. However, because the graph has a cycle, the output is not a valid topological order.
DFS visits all descendants of a node before pushing the node itself onto the stack. This ensures that dependencies come before dependents in the final order, which is the essence of topological sorting.
