 GFG App
Open App Browser
Continue

# Lexicographically Smallest Topological Ordering

Given a directed graph with N vertices and M edges that may contain cycles, the task is to find the lexicographically smallest topological ordering of the graph if it exists otherwise print -1 (if the graph has cycles).
Lexicographically smallest topological ordering means that if two vertices in a graph do not have any incoming edge then the vertex with the smaller number should appear first in the ordering.
For Example, in the image below many topological orderings are possible e.g 5 2 3 4 0 1, 5 0 2 4 3 1
But the smallest ordering is 4 5 0 2 3 1.
Examples:

Input: Output: 4 5 0 2 3 1
Even though 5 4 0 2 3 1 is also a valid topological
ordering of the given graph but it is not
lexicographically smallest.

Approach: We will use Kahn’s algorithm for Topological Sorting with a modification. Instead of using a queue we will use a multiset to store the vertices to make sure that every time we pick a vertex it is the smallest possible of all. The overall Time complexity changes to Below is the implementation of the above approach:

## CPP

 `// C++ implementation of the approach` `#include` `using` `namespace` `std;`   `vector> adj;`     `// function to add edge to the graph` `void` `addEdge(``int` `x,``int` `y)` `{` `    ``adj[x].push_back(y);` `}`   `// Function to print the required topological` `// sort of the given graph` `void` `topologicalSort()` `{` `    ``int` `V = adj.size();` `    ``// Create a vector to store indegrees of all` `    ``// the vertices` `    ``// Initialize all indegrees to 0` `    ``vector<``int``> in_degree(V, 0);` ` `  `    ``// Traverse adjacency lists to fill indegrees of` `    ``// vertices` `    ``// This step takes O(V+E) time` `    ``for` `(``int` `u = 0; u < V; u++) {` `        ``for` `(``auto` `x: adj[u])` `            ``in_degree[x]++;` `    ``}` ` `  `    ``// Create a set and inserting all vertices with` `    ``// indegree 0` `    ``multiset<``int``> s;` `    ``for` `(``int` `i = 0; i < V; i++)` `        ``if` `(in_degree[i] == 0)` `            ``s.insert(i);` ` `  `    ``// Initialize count of visited vertices` `    ``int` `cnt = 0;` ` `  `    ``// Create a vector to store result (A topological` `    ``// ordering of the vertices)` `    ``vector<``int``> top_order;` ` `  `    ``// One by one erase vertices from setand insert` `    ``// adjacents if indegree of adjacent becomes 0` `    ``while` `(!s.empty()) {` ` `  `        ``// Extract vertex with minimum number from multiset` `        ``// and add it to topological order` `        ``int` `u = *s.begin();` `        ``s.erase(s.begin());` `        ``top_order.push_back(u);` ` `  `        ``// Iterate through all its neighbouring nodes` `        ``// of erased node u and decrease their in-degree` `        ``// by 1` `        ``for` `(``auto` `x:adj[u])` ` `  `            ``// If in-degree becomes zero, add it to queue` `            ``if` `(--in_degree[x] == 0)` `                ``s.insert(x);` ` `  `        ``cnt++;` `    ``}` ` `  `    ``// Check if there was a cycle` `    ``if` `(cnt != V) {` `        ``cout << -1;` `        ``return``;` `    ``}` ` `  `    ``// Print topological order` `    ``for` `(``int` `i = 0; i < top_order.size(); i++)` `        ``cout << top_order[i] << ``" "``;` `}` `int` `main()` `{` `  ``// number of vertices` `  ``int` `v = 6;`     `  ``// adjacency matrix` `  ``adj= vector>(v);`   `  ``addEdge(5,2);` `  ``addEdge(5,0);` `  ``addEdge(4,0);` `  ``addEdge(4,1);` `  ``addEdge(2,3);` `  ``addEdge(3,1);` `  `  `  ``// find required topological order` `  ``topologicalSort();` `}`

## Java

 `// Java implementation of the approach` `import` `java.util.*;`   `class` `Main` `{` `  ``static` `List> adj;` `  `  `  ``// function to add edge to the graph` `  ``static` `void` `addEdge(``int` `x,``int` `y)` `  ``{` `    ``adj.get(x).add(y);` `  ``}`   `  ``// Function to print the required topological` `  ``// sort of the given graph` `  ``static` `void` `topologicalSort()` `  ``{` `    ``int` `V = adj.size();` `    `  `    ``// Create a vector to store indegrees of all` `    ``// the vertices` `    ``// Initialize all indegrees to 0` `    ``int``[] in_degree = ``new` `int``[V];` `    ``Arrays.fill(in_degree, ``0``);`   `    ``// Traverse adjacency lists to fill indegrees of` `    ``// vertices` `    ``// This step takes O(V+E) time` `    ``for` `(``int` `u = ``0``; u < V; u++) {` `      ``for` `(``int` `x: adj.get(u))` `        ``in_degree[x]++;` `    ``}`   `    ``// Create a queue and inserting all vertices with` `    ``// indegree 0` `    ``PriorityQueue queue = ``new` `PriorityQueue<>();` `    ``for` `(``int` `i = ``0``; i < V; i++)` `      ``if` `(in_degree[i] == ``0``)` `        ``queue.add(i);`   `    ``// Initialize count of visited vertices` `    ``int` `cnt = ``0``;`   `    ``// Create a vector to store result (A topological` `    ``// ordering of the vertices)` `    ``List top_order = ``new` `ArrayList<>();`   `    ``// One by one erase vertices from queue and insert` `    ``// adjacents if indegree of adjacent becomes 0` `    ``while` `(!queue.isEmpty()) {`   `      ``// Extract vertex with minimum number from queue` `      ``// and add it to topological order` `      ``int` `u = queue.poll();` `      ``top_order.add(u);`   `      ``// Iterate through all its neighbouring nodes` `      ``// of erased node u and decrease their in-degree` `      ``// by 1` `      ``for` `(``int` `x: adj.get(u))`   `        ``// If in-degree becomes zero, add it to queue` `        ``if` `(--in_degree[x] == ``0``)` `          ``queue.add(x);`   `      ``cnt++;` `    ``}`   `    ``// Check if there was a cycle` `    ``if` `(cnt != V) {` `      ``System.out.println(-``1``);` `      ``return``;` `    ``}`   `    ``// Print topological order` `    ``for` `(``int` `i = ``0``; i < top_order.size(); i++)` `      ``System.out.print(top_order.get(i) + ``" "``);` `  ``}` `  ``public` `static` `void` `main (String[] args)` `  ``{` `    ``// number of vertices` `    ``int` `v = ``6``;`     `    ``// adjacency matrix` `    ``adj = ``new` `ArrayList<>(v);` `    ``for` `(``int` `i = ``0``; i < v; i++) {` `      ``adj.add(``new` `ArrayList<>());` `    ``}`   `    ``addEdge(``5``,``2``);` `    ``addEdge(``5``,``0``);` `    ``addEdge(``4``,``0``);` `    ``addEdge(``4``,``1``);` `    ``addEdge(``2``,``3``);` `    ``addEdge(``3``,``1``);`   `    ``// find required topological order` `    ``topologicalSort();` `  ``}` `}`   `// This code is contributed by lokeshpotta20.`

## Python3

 `# Python3 implementation of the approach` `import` `heapq as hq`       `# function to add edge to the graph` `def` `addEdge(x, y):` `    ``adj[x].append(y)`     `# Function to print required topological` `# sort of the given graph` `def` `topologicalSort():` `    ``V ``=` `len``(adj)` `    ``# Create a vector to store indegrees of all` `    ``# the vertices` `    ``# Initialize all indegrees to 0` `    ``in_degree ``=` `[``0``] ``*` `V`   `    ``# Traverse adjacency lists to fill indegrees of` `    ``# vertices` `    ``# This step takes O(V+E) time` `    ``for` `u ``in` `range``(V):` `        ``for` `x ``in` `adj[u]:` `            ``in_degree[x] ``+``=` `1` `    ``# Create a heap and inserting all vertices with` `    ``# indegree 0` `    ``s ``=` `[]` `    ``for` `i ``in` `range``(V):` `        ``if` `in_degree[i] ``=``=` `0``:` `            ``hq.heappush(s, i)`   `    ``# Initialize count of visited vertices` `    ``cnt ``=` `0`   `    ``# Create a vector to store result (A topological` `    ``# ordering of the vertices)` `    ``top_order ``=` `[]`   `    ``# One by one erase vertices from setand insert` `    ``# adjacents if indegree of adjacent becomes 0` `    ``while` `s:`   `        ``# Extract vertex with minimum number from multiset` `        ``# and add it to topological order` `        ``u ``=` `hq.heappop(s)` `        ``top_order.append(u)`   `        ``# Iterate through all its neighbouring nodes` `        ``# of erased node u and decrease their in-degree` `        ``# by 1` `        ``for` `x ``in` `adj[u]:` `            ``in_degree[x] ``-``=` `1` `            ``# If in-degree becomes zero, add it to queue` `            ``if` `in_degree[x] ``=``=` `0``:` `                ``hq.heappush(s, x)`   `        ``cnt ``+``=` `1`   `    ``# Check if there was a cycle` `    ``if` `cnt !``=` `V:` `        ``print``(``-``1``)` `        ``return`   `    ``# Print topological order` `    ``for` `i ``in` `range``(``len``(top_order)):` `        ``print``(top_order[i], end``=``" "``)`     `if` `__name__ ``=``=` `"__main__"``:` `    ``# number of vertices` `    ``v ``=` `6`   `    ``# adjacency matrix` `    ``adj ``=` `[[] ``for` `_ ``in` `range``(v)]`   `    ``addEdge(``5``, ``2``)` `    ``addEdge(``5``, ``0``)` `    ``addEdge(``4``, ``0``)` `    ``addEdge(``4``, ``1``)` `    ``addEdge(``2``, ``3``)` `    ``addEdge(``3``, ``1``)`   `    ``# find required topological order` `    ``topologicalSort()`

## C#

 `using` `System;` `using` `System.Collections.Generic;` `using` `System.Linq;`   `class` `MainClass` `{` `    ``static` `List> adj;`   `    ``// function to add edge to the graph` `    ``static` `void` `AddEdge(``int` `x, ``int` `y)` `    ``{` `        ``adj[x].Add(y);` `    ``}`   `    ``// Function to print the required topological` `    ``// sort of the given graph` `    ``static` `void` `TopologicalSort()` `    ``{` `        ``int` `V = adj.Count;`   `        ``// Create an array to store indegrees of all` `        ``// the vertices` `        ``// Initialize all indegrees to 0` `        ``int``[] in_degree = ``new` `int``[V];` `        ``for` `(``int` `i = 0; i < V; i++)` `        ``{` `            ``in_degree[i] = 0;` `        ``}`   `        ``// Traverse adjacency lists to fill indegrees of` `        ``// vertices` `        ``// This step takes O(V+E) time` `        ``for` `(``int` `u = 0; u < V; u++)` `        ``{` `            ``foreach` `(``int` `x ``in` `adj[u])` `            ``{` `                ``in_degree[x]++;` `            ``}` `        ``}`   `        ``// Create a queue and inserting all vertices with` `        ``// indegree 0` `        ``Queue<``int``> queue = ``new` `Queue<``int``>();` `        ``for` `(``int` `i = 0; i < V; i++)` `        ``{` `            ``if` `(in_degree[i] == 0)` `            ``{` `                ``queue.Enqueue(i);` `            ``}` `        ``}`   `        ``// Initialize count of visited vertices` `        ``int` `cnt = 0;`   `        ``// Create a list to store result (A topological` `        ``// ordering of the vertices)` `        ``List<``int``> top_order = ``new` `List<``int``>();`   `        ``// One by one erase vertices from queue and insert` `        ``// adjacents if indegree of adjacent becomes 0` `        ``while` `(queue.Count != 0)` `        ``{`   `            ``// Extract vertex with minimum number from queue` `            ``// and add it to topological order` `            ``int` `u = queue.Dequeue();` `            ``top_order.Add(u);`   `            ``// Iterate through all its neighbouring nodes` `            ``// of erased node u and decrease their in-degree` `            ``// by 1` `            ``foreach` `(``int` `x ``in` `adj[u])` `            ``{`   `                ``// If in-degree becomes zero, add it to queue` `                ``if` `(--in_degree[x] == 0)` `                ``{` `                    ``queue.Enqueue(x);` `                ``}` `            ``}`   `            ``cnt++;` `        ``}`   `        ``// Check if there was a cycle` `        ``if` `(cnt != V)` `        ``{` `            ``Console.WriteLine(-1);` `            ``return``;` `        ``}`   `        ``// Print topological order` `        ``foreach` `(``int` `i ``in` `top_order)` `        ``{` `            ``Console.Write(i + ``" "``);` `        ``}` `    ``}`   `    ``public` `static` `void` `Main()` `    ``{` `        ``// number of vertices` `        ``int` `v = 6;`   `        ``// adjacency matrix` `        ``adj = ``new` `List>(v);` `        ``for` `(``int` `i = 0; i < v; i++)` `        ``{` `            ``adj.Add(``new` `List<``int``>());` `        ``}`   `        ``AddEdge(5, 2);` `        ``AddEdge(5, 0);` `        ``AddEdge(4, 0);` `        ``AddEdge(4, 1);` `        ``AddEdge(2, 3);` `        ``AddEdge(3, 1);`   `        ``// find required topological order` `        ``TopologicalSort();` `    ``}` `}`

## Javascript

 `// JavaScript implementation of the approach`   `// adjacency matrix` `let adj = [];`   `// function to add edge to the graph` `function` `addEdge(x, y) {` `    ``adj[x].push(y);` `}`   `// Function to print the required topological` `// sort of the given graph` `function` `topologicalSort() {` `    ``let V = adj.length;`   `    ``// Create a vector to store indegrees of all` `    ``// the vertices` `    ``// Initialize all indegrees to 0` `    ``let in_degree = Array(V).fill(0);`   `    ``// Traverse adjacency lists to fill indegrees of` `    ``// vertices` `    ``// This step takes O(V+E) time` `    ``for` `(let u = 0; u < V; u++) {` `        ``for` `(let i = 0; i < adj[u].length; i++)` `            ``in_degree[adj[u][i]]++;` `    ``}`   `    ``// Create a set and inserting all vertices with` `    ``// indegree 0` `    ``let s = ``new` `Set();` `    ``for` `(let i = 0; i < V; i++)` `        ``if` `(in_degree[i] == 0)` `            ``s.add(i);`   `    ``// Initialize count of visited vertices` `    ``let cnt = 0;`   `    ``// Create a vector to store result (A topological` `    ``// ordering of the vertices)` `    ``let top_order = [];`   `    ``// One by one erase vertices from setand insert` `    ``// adjacents if indegree of adjacent becomes 0` `    ``while` `(s.size > 0) {`   `        ``// Extract vertex with minimum number from multiset` `        ``// and add it to topological order` `        ``let u = s.values().next().value;` `        ``s.``delete``(u);` `        ``top_order.push(u);`   `        ``// Iterate through all its neighbouring nodes` `        ``// of erased node u and decrease their in-degree` `        ``// by 1` `        ``for` `(let i = 0; i < adj[u].length; i++) {` `            ``// If in-degree becomes zero, add it to queue` `            ``if` `(--in_degree[adj[u][i]] == 0)` `                ``s.add(adj[u][i]);` `        ``}`   `        ``cnt++;` `    ``}`   `    ``// Check if there was a cycle` `    ``if` `(cnt != V) {` `        ``console.log(-1);` `        ``return``;` `    ``}`   `    ``// Print topological order` `    ``console.log(top_order);` `}`   `function` `main() {` `    ``// number of vertices` `    ``let v = 6;`   `    ``// adjacency matrix` `    ``for` `(let i = 0; i < v; i++)` `        ``adj.push([]);`   `    ``addEdge(5, 2);` `    ``addEdge(5, 0);` `    ``addEdge(4, 0);` `    ``addEdge(4, 1);` `    ``addEdge(2, 3);` `    ``addEdge(3, 1);`   `    ``// find required topological order` `    ``topologicalSort();` `}`   `main();`

Output:

`4 5 0 2 3 1`

Time Complexity: O(N)
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up