Topological Sort (Kahn's Algorithm)

Concept

Topological sort orders nodes of a DAG (Directed Acyclic Graph) so that for every edge u -> v, u comes before v. Kahn's algorithm uses BFS with in-degree counting: start from nodes with in-degree 0, remove them, decrease neighbors' in-degrees, and repeat.

When to Use

  • Course prerequisites — finding a valid order to take courses
  • Task scheduling with dependencies
  • Build systems (compile order)
  • Detecting if a directed graph has a cycle (if topo sort doesn't include all nodes, there's a cycle)

Intuition

Think of courses with prerequisites. Start with courses that have no prerequisites (in-degree 0) — you can take them right away. After completing them, some new courses become available (their prerequisites are now met). Take those next. Repeat until all courses are taken. If you get stuck with remaining courses that all have unmet prerequisites, there's a circular dependency (cycle).

Complexity

Time
O(V + E)
Space
O(V + E)

Template Code

cpp
#include<bits/stdc++.h>
using namespace std;

int main(){
    ios_base::sync_with_stdio(0), cin.tie(0);

    int numCourses, m;
    cin >> numCourses >> m;

    vector<vector<int>> adj(numCourses);
    vector<int> inde(numCourses, 0);
    vector<int> order;

    for(int i = 0; i < m; i++){
        int a, b;
        cin >> a >> b;
        adj[b].push_back(a);
        inde[a]++;
    }

    queue<int> q;
    for(int i = 0; i < numCourses; i++){
        if(inde[i] == 0) q.push(i);
    }

    while(!q.empty()){
        int u = q.front();
        q.pop();

        order.push_back(u);

        for(int &v : adj[u]){
            inde[v]--;
            if(inde[v] == 0) q.push(v);
        }
    }

    if(order.size() != numCourses){
        cout << "IMPOSSIBLE\n";
    }
    else{
        for(int &x : order){
            cout << x << " ";
        }
        cout << "\n";
    }

    return 0;
}

// Sample Input:
// 4 4
// 1 0
// 2 0
// 3 1
// 3 2
//
// Sample Output:
// 0 1 2 3