Open In App

Print the lexicographically smallest DFS of the graph starting from 1

Last Updated : 29 Oct, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a connected graph with N vertices and M edges. The task is to print the lexicographically smallest DFS traversal of the graph starting from 1. Note that the vertices are numbered from 1 to N.
Examples: 
 

Input: N = 5, M = 5, edges[] = {{1, 4}, {3, 4}, {5, 4}, {3, 2}, {1, 5}} 
Output: 1 4 3 2 5
Input: N = 5, M = 8, edges[] = {{1, 4}, {3, 4}, {5, 4}, {3, 2}, {1, 5}, {1, 2}, {1, 3}, {3, 5}} 
Output: 1 2 3 4 5 
 

 

Approach: Instead of doing a normal DFS, first we have to sort the edges of each vertex, so that in each turn only the smallest edge is picked first. After sorting, just perform a normal DFS which will give the lexicographically smallest DFS traversal.
Below is the implementation of the above approach: 
 

C++




// C++ program to find the lexicographically
// smallest traversal of a graph
#include <bits/stdc++.h>
using namespace std;
 
// Utility function to add an
// edge to the graph
void insertEdges(int u, int v, vector<int>* adj)
{
    adj[u].push_back(v);
    adj[v].push_back(u);
}
 
// Function to perform DFS traversal
void dfs(vector<int>* adj, int src, int n,
         bool* visited)
{
    // Print current vertex
    cout << src << " ";
 
    // Mark it as visited
    visited[src] = true;
 
    // Iterate over all the edges connected
    // to this vertex
    for (int i = 0; i < adj[src].size(); i++) {
        // If this vertex is not visited,
        /// call dfs from this node
        if (!visited[adj[src][i]])
            dfs(adj, adj[src][i], n, visited);
    }
}
 
// Function to print the lexicographically
// smallest DFS
void printLexoSmall(vector<int>* adj, int n)
{
    // A boolean array to keep track of
    // nodes visited
    bool visited[n + 1] = { 0 };
 
    // Sort the edges of each vertex in
    // ascending order
    for (int i = 0; i < n; i++)
        sort(adj[i].begin(), adj[i].end());
 
    // Call DFS
    for (int i = 1; i < n; i++) {
        if (!visited[i])
            dfs(adj, i, n, visited);
    }
}
 
// Driver code
int main()
{
    int n = 5, m = 5;
    vector<int> adj[n + 1];
 
    insertEdges(1, 4, adj);
    insertEdges(3, 4, adj);
    insertEdges(5, 4, adj);
    insertEdges(3, 2, adj);
    insertEdges(1, 5, adj);
    insertEdges(1, 2, adj);
    insertEdges(3, 5, adj);
    insertEdges(1, 3, adj);
 
    printLexoSmall(adj, n);
 
    return 0;
}


Java




// Java program to find the lexicographically
// smallest traversal of a graph
import java.util.*;
 
class GFG
{
 
    static boolean visited[];
    static Vector<Vector<Integer>> adj = new Vector<Vector<Integer>>();
     
// Utility function to add an
// edge to the graph
static void insertEdges(int u, int v)
{
    adj.get(u).add(v);
    adj.get(v).add(u);
}
 
// Function to perform DFS traversal
static void dfs( int src, int n)
{
    // Print current vertex
    System.out.print( src + " ");
 
    // Mark it as visited
    visited[src] = true;
 
    // Iterate over all the edges connected
    // to this vertex
    for (int i = 0; i < adj.get(src).size(); i++)
    {
        // If this vertex is not visited,
        /// call dfs from this node
        if (!visited[adj.get(src).get(i)])
            dfs( adj.get(src).get(i), n);
    }
}
 
// Function to print the lexicographically
// smallest DFS
static void printLexoSmall( int n)
{
    // A boolean array to keep track of
    // nodes visited
    visited= new boolean[n + 1];
     
    // Sort the edges of each vertex in
    // ascending order
    for (int i = 0; i < n; i++)
        Collections.sort(adj.get(i));
 
    // Call DFS
    for (int i = 1; i < n; i++)
    {
        if (!visited[i])
            dfs( i, n);
    }
}
 
// Driver code
public static void main(String args[])
{
    int n = 5, m = 5;
     
    for(int i = 0; i < n + 1; i++)
    adj.add(new Vector<Integer>());
     
    insertEdges(1, 4);
    insertEdges(3, 4);
    insertEdges(5, 4);
    insertEdges(3, 2);
    insertEdges(1, 5);
    insertEdges(1, 2);
    insertEdges(3, 5);
    insertEdges(1, 3);
 
    printLexoSmall( n);
}
}
 
// This code is contributed by Arnab Kundu


Python3




# Python3 program to find the lexicographically
# smallest traversal of a graph
 
# Utility function to add an edge
# to the graph
def insertEdges(u, v, adj):
 
    adj[u].append(v)
    adj[v].append(u)
 
# Function to perform DFS traversal
def dfs(adj, src, n, visited):
 
    # Print current vertex
    print(src, end = " ")
 
    # Mark it as visited
    visited[src] = True
 
    # Iterate over all the edges
    # connected to this vertex
    for i in range(0, len(adj[src])):
         
        # If this vertex is not visited,
        # call dfs from this node
        if not visited[adj[src][i]]:
            dfs(adj, adj[src][i], n, visited)
 
# Function to print the lexicographically
# smallest DFS
def printLexoSmall(adj, n):
 
    # A boolean array to keep track
    # of nodes visited
    visited = [0] * (n + 1)
 
    # Sort the edges of each vertex 
    # in ascending order
    for i in range(0, n):
        adj[i].sort()
 
    # Call DFS
    for i in range(1, n):
        if not visited[i]:
            dfs(adj, i, n, visited)
 
# Driver code
if __name__ == "__main__":
 
    n, m = 5, 5
    adj = [[] for i in range(n + 1)]
 
    insertEdges(1, 4, adj)
    insertEdges(3, 4, adj)
    insertEdges(5, 4, adj)
    insertEdges(3, 2, adj)
    insertEdges(1, 5, adj)
    insertEdges(1, 2, adj)
    insertEdges(3, 5, adj)
    insertEdges(1, 3, adj)
 
    printLexoSmall(adj, n)
 
# This code is contributed by Rituraj Jain


C#




// C# program to find the lexicographically
// smallest traversal of a graph
using System;
using System.Collections.Generic;
 
class GFG
{
 
    public static bool[] visited;
    public static List<List<int>> adj = new List<List<int>>();
 
// Utility function to add an
// edge to the graph
public static void insertEdges(int u, int v)
{
    adj[u].Add(v);
    adj[v].Add(u);
}
 
// Function to perform DFS traversal
public static void dfs(int src, int n)
{
    // Print current vertex
    Console.Write(src + " ");
 
    // Mark it as visited
    visited[src] = true;
 
    // Iterate over all the edges connected
    // to this vertex
    for (int i = 0; i < adj[src].Count; i++)
    {
        // If this vertex is not visited,
        /// call dfs from this node
        if (!visited[adj[src][i]])
        {
            dfs(adj[src][i], n);
        }
    }
}
 
// Function to print the lexicographically
// smallest DFS
public static void printLexoSmall(int n)
{
    // A boolean array to keep track of
    // nodes visited
    visited = new bool[n + 1];
 
    // Sort the edges of each vertex in
    // ascending order
    for (int i = 0; i < n; i++)
    {
        adj[i].Sort();
    }
 
    // Call DFS
    for (int i = 1; i < n; i++)
    {
        if (!visited[i])
        {
            dfs(i, n);
        }
    }
}
 
// Driver code
public static void Main(string[] args)
{
    int n = 5, m = 5;
 
    for (int i = 0; i < n + 1; i++)
    {
        adj.Add(new List<int>());
    }
 
    insertEdges(1, 4);
    insertEdges(3, 4);
    insertEdges(5, 4);
    insertEdges(3, 2);
    insertEdges(1, 5);
    insertEdges(1, 2);
    insertEdges(3, 5);
    insertEdges(1, 3);
 
    printLexoSmall(n);
}
}
 
// This code is contributed by shrikanth13


Javascript




<script>
// Javascript program to find the lexicographically
// smallest traversal of a graph
 
let visited;
let adj =[] ;
 
// Utility function to add an
// edge to the graph
function insertEdges(u,v)
{
    adj[u].push(v);
    adj[v].push(u);
}
 
// Function to perform DFS traversal
function dfs(src,n)
{
    // Print current vertex
    document.write( src + " ");
   
    // Mark it as visited
    visited[src] = true;
   
    // Iterate over all the edges connected
    // to this vertex
    for (let i = 0; i < adj[src].length; i++)
    {
        // If this vertex is not visited,
        /// call dfs from this node
        if (!visited[adj[src][i]])
            dfs( adj[src][i], n);
    }
}
 
// Function to print the lexicographically
// smallest DFS
function printLexoSmall(n)
{
    // A boolean array to keep track of
    // nodes visited
    visited= new Array(n + 1);
       
    // Sort the edges of each vertex in
    // ascending order
    for (let i = 0; i < n; i++)
        adj[i].sort(function(a,b){return a-b;});
   
    // Call DFS
    for (let i = 1; i < n; i++)
    {
        if (!visited[i])
            dfs( i, n);
    }
}
 
// Driver code
let n = 5, m = 5;
       
for(let i = 0; i < n + 1; i++)
    adj.push([]);
 
insertEdges(1, 4);
insertEdges(3, 4);
insertEdges(5, 4);
insertEdges(3, 2);
insertEdges(1, 5);
insertEdges(1, 2);
insertEdges(3, 5);
insertEdges(1, 3);
 
printLexoSmall( n);
 
// This code is contributed by avanitrachhadiya2155
</script>


Output

1 2 3 4 5

Approach#2: Using DFS Algorithm with Priority Queue

This Approach builds a graph from the given edges, then performs a DFS traversal starting from node 1 using a priority queue to keep track of the lexicographically smallest path. The resulting path is returned as a list.

Algorithm

1. Build the adjacency list of the graph using the given edges.
2. Start the DFS from node 1 and push it into a priority queue.
3. While the priority queue is not empty, pop the node with the smallest value and visit it.
4. For each unvisited neighbor of the current node, push it into the priority queue.
5. Repeat steps 3-4 until all nodes are visited.

C++




#include<bits/stdc++.h>
using namespace std;
 
vector<vector<int>> build_graph(vector<vector<int>>& edges) {
    vector<vector<int>> graph(edges.size() + 1);
    for (auto& edge : edges) {
        graph[edge[0]].push_back(edge[1]);
        graph[edge[1]].push_back(edge[0]);
    }
    return graph;
}
 
vector<int> dfs(vector<vector<int>>& graph, int start) {
    set<int> visited;
    priority_queue<int, vector<int>, greater<int>> pq;
    vector<int> result;
    pq.push(start);
    while (!pq.empty()) {
        int node = pq.top();
        pq.pop();
        if (visited.count(node)) {
            continue;
        }
        visited.insert(node);
        result.push_back(node);
        for (auto& neighbor : graph[node]) {
            if (!visited.count(neighbor)) {
                pq.push(neighbor);
            }
        }
    }
    return result;
}
 
vector<int> lex_smallest_dfs(int n, int m, vector<vector<int>>& edges) {
    auto graph = build_graph(edges);
    return dfs(graph, 1);
}
 
int main() {
    int n = 5;
    int m = 5;
    vector<vector<int>> edges{{1, 4}, {3, 4}, {5, 4}, {3, 2}, {1, 5}};
    auto result = lex_smallest_dfs(n, m, edges);
    for (auto& node : result) {
        cout << node << " ";
    }
    cout << endl;
    return 0;
}
// This code is contributed by Prajwal Kandekar


Java




import java.util.*;
 
public class Main {
  public static List<List<Integer> >
    buildGraph(List<List<Integer> > edges)
  {
    List<List<Integer> > graph
      = new ArrayList<>(edges.size() + 1);
    for (int i = 0; i < edges.size() + 1; i++) {
      graph.add(new ArrayList<Integer>());
    }
    for (List<Integer> edge : edges) {
      int u = edge.get(0);
      int v = edge.get(1);
      graph.get(u).add(v);
      graph.get(v).add(u);
    }
    return graph;
  }
 
  public static List<Integer>
    dfs(List<List<Integer> > graph, int start)
  {
    Set<Integer> visited = new HashSet<>();
    PriorityQueue<Integer> pq = new PriorityQueue<>(
      Comparator.comparingInt(a -> a));
    List<Integer> result = new ArrayList<>();
    pq.offer(start);
    while (!pq.isEmpty()) {
      int node = pq.poll();
      if (visited.contains(node)) {
        continue;
      }
      visited.add(node);
      result.add(node);
      for (int neighbor : graph.get(node)) {
        if (!visited.contains(neighbor)) {
          pq.offer(neighbor);
        }
      }
    }
    return result;
  }
 
  public static List<Integer>
    lexSmallestDfs(int n, int m, List<List<Integer> > edges)
  {
    List<List<Integer> > graph = buildGraph(edges);
    return dfs(graph, 1);
  }
 
  public static void main(String[] args)
  {
    int n = 5;
    int m = 5;
    List<List<Integer> > edges = new ArrayList<>();
    edges.add(Arrays.asList(1, 4));
    edges.add(Arrays.asList(3, 4));
    edges.add(Arrays.asList(5, 4));
    edges.add(Arrays.asList(3, 2));
    edges.add(Arrays.asList(1, 5));
    List<Integer> result = lexSmallestDfs(n, m, edges);
    for (int node : result) {
      System.out.print(node + " ");
    }
    System.out.println();
  }
}


Python3




import heapq
 
def build_graph(edges):
    graph = [[] for _ in range(len(edges)+1)]
    for a, b in edges:
        graph[a].append(b)
        graph[b].append(a)
    return graph
 
def dfs(graph, start):
    visited = set()
    pq = [start]
    result = []
    while pq:
        node = heapq.heappop(pq)
        if node in visited:
            continue
        visited.add(node)
        result.append(node)
        for neighbor in graph[node]:
            if neighbor not in visited:
                heapq.heappush(pq, neighbor)
    return result
 
def lex_smallest_dfs(n, m, edges):
    graph = build_graph(edges)
    return dfs(graph, 1)
 
# Example usage:
n = 5
m = 5
edges = [[1, 4], [3, 4], [5, 4], [3, 2], [1, 5]]
print(lex_smallest_dfs(n, m, edges))


C#




using System;
using System.Collections.Generic;
 
class Program
{
    static List<List<int>> BuildGraph(List<int[]> edges)
    {
        List<List<int>> graph = new List<List<int>>(edges.Count + 1);
        for (int i = 0; i <= edges.Count; i++)
        {
            graph.Add(new List<int>());
        }
        foreach (int[] edge in edges)
        {
            graph[edge[0]].Add(edge[1]);
            graph[edge[1]].Add(edge[0]);
        }
        return graph;
    }
 
    static List<int> DFS(List<List<int>> graph, int start)
    {
        HashSet<int> visited = new HashSet<int>();
        Queue<int> queue = new Queue<int>();
        List<int> result = new List<int>();
        queue.Enqueue(start);
        while (queue.Count > 0)
        {
            int node = queue.Dequeue();
            if (visited.Contains(node))
            {
                continue;
            }
            visited.Add(node);
            result.Add(node);
            foreach (int neighbor in graph[node])
            {
                if (!visited.Contains(neighbor))
                {
                    queue.Enqueue(neighbor);
                }
            }
        }
        return result;
    }
 
    static List<int> LexSmallestDFS(int n, int m, List<int[]> edges)
    {
        List<List<int>> graph = BuildGraph(edges);
        return DFS(graph, 1);
    }
 
    static void Main()
    {
        int n = 5;
        int m = 5;
        List<int[]> edges = new List<int[]>
        {
            new int[] { 1, 4 },
            new int[] { 3, 4 },
            new int[] { 5, 4 },
            new int[] { 3, 2 },
            new int[] { 1, 5 }
        };
        List<int> result = LexSmallestDFS(n, m, edges);
        foreach (int node in result)
        {
            Console.Write(node + " ");
        }
        Console.WriteLine();
    }
}


Javascript




function buildGraph(edges) {
     // create an empty array to hold graph nodes
  let graph = new Array(edges.length + 1).fill().map(() => []);
  for (let [u, v] of edges) {
// add the edge to the graph (undirected, so add it in both directions)
    graph[u].push(v);
    graph[v].push(u);
  }
  return graph;
}
 
function dfs(graph, start) {
// set to track visited nodes
  let visited = new Set();
  // priority queue () to store nodes to be visited
  let pq = [start];
  // list to store the result in the order of visitation
  let result = [];
  while (pq.length > 0) {
     
  // remove the node with the smallest label from the queue
    let node = pq.shift();
 
  // if it's already been visited, skip it
    if (visited.has(node)) continue;
   
  // mark the node as visited
    visited.add(node);
  
 // add the node to the result list
    result.push(node);
    for (let neighbor of graph[node]) {
      if (!visited.has(neighbor)) pq.push(neighbor);
    }
    pq.sort((a, b) => a - b); // sort the priority queue
  }
  return result;
}
 
function lexSmallestDfs(n, m, edges) {
  let graph = buildGraph(edges);
  return dfs(graph, 1);
}
 
// Example usage:
let n = 5;
let m = 5;
let edges = [[1, 4], [3, 4], [5, 4], [3, 2], [1, 5]];
console.log(lexSmallestDfs(n, m, edges)); // output: [1, 4, 3, 2, 5]


Output

[1, 4, 3, 2, 5]

Time Complexity: O(m log n) where m is the number of edges and n is the number of nodes in the graph.
Auxiliary Space: O(n+m)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads