Smallest set of vertices to visit all nodes of the given Graph
Last Updated :
11 Jan, 2025
Given a directed acyclic graph of N nodes, the task is to find the smallest set of vertices from which the complete graph can be visited.
Examples:
Input: Graph in the image below

Output: 0 4
Explanation: From vertex 0, the set of nodes that can be visited is {0 ,1}. Similarly, from vertex 4, {4, 3, 2} can be visited. Hence, the complete graph can be visited from the set {0, 4} which is of the minimum possible size.
Input: Graph in the image below

Output: 3 4
Approach 1: The given problem can be solved using topological sorting to get the ordering of vertices such that for every directed edge from U to V, U comes before V. Below are the steps to follow:
- Sort the given array of vertices in topological order using Kahn's Algorithm.
- Maintain an array visited which keeps track of the visited vertices.
- Iterate the sorted array perform the following operations:
- If the current vertex is not visited, insert it into the required set.
- Visit all the nodes that are reachable from the inserted node using DFS traversal.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
// Function to perform DFS
void dfs(int node, unordered_set<int>& vis,
map<int, vector<int> >& graph)
{
// add node to visited set
vis.insert(node);
for (int adj : graph[node]) {
if (vis.count(adj) == 0) {
dfs(adj, vis, graph);
}
}
}
vector<int> solve(vector<vector<int> >& edges)
{
map<int, vector<int> > graph;
// dictionary storing
// indegrees of node
map<int, int> indeg;
// array to store topological
// sorting of the array
vector<int> topo_sort;
unordered_set<int> vis;
for (auto edge : edges) {
int u = edge[0], v = edge[1];
graph[u].push_back(v);
// count indegree of each node
indeg[v]++;
}
queue<int> qu;
for (auto u : graph) {
// add to queue, if indegree
// of node u is 0
if (indeg[u.first] == 0) {
qu.push(u.first);
}
}
// Run till queue is not empty
while (!qu.empty()) {
int node = qu.front();
qu.pop();
// add node to topo_sort
topo_sort.push_back(node);
// traverse adj nodes
for (int adj : graph[node]) {
// decrement count of indegree
// of each adj node by 1
indeg[adj]--;
// if count becomes 0, then
// add adj to qu
if (indeg[adj] == 0) {
qu.push(adj);
}
}
}
vis.clear();
vector<int> ans;
// Take each node from topo_sort
for (int node : topo_sort) {
// check if node is visited
if (vis.count(node) == 0) {
vis.insert(node);
ans.push_back(node);
// Mark all the reachable
// nodes as visited
dfs(node, vis, graph);
}
}
// finally return ans
return ans;
}
};
// Driver code
int main()
{
Solution obj;
vector<vector<int> > edges
= { { 0, 1 }, { 2, 1 }, { 3, 2 }, { 4, 3 } };
// Function call
vector<int> ans = obj.solve(edges);
for (int n : ans) {
cout << n << " ";
}
cout << endl;
return 0;
}
Java
//GFG
// JAVA program of the above approach
import java.util.*;
public class Solution {
// Function to perform DFS
private void dfs(int node, Set<Integer> vis, Map<Integer, List<Integer>> graph) {
vis.add(node);
for (int adj : graph.getOrDefault(node, new ArrayList<>())) {
if (!vis.contains(adj)) {
dfs(adj, vis, graph);
}
}
}
public List<Integer> solve(int[][] edges) {
Map<Integer, List<Integer>> graph = new HashMap<>();
Map<Integer, Integer> indeg = new HashMap<>();
List<Integer> topoSort = new ArrayList<>();
Set<Integer> vis = new HashSet<>();
for (int[] edge : edges) {
int u = edge[0];
int v = edge[1];
graph.putIfAbsent(u, new ArrayList<>());
graph.get(u).add(v);
indeg.put(v, indeg.getOrDefault(v, 0) + 1);
}
Queue<Integer> qu = new LinkedList<>();
for (int u : graph.keySet()) {
if (!indeg.containsKey(u)) {
qu.offer(u);
}
}
while (!qu.isEmpty()) {
int node = qu.poll();
topoSort.add(node);
for (int adj : graph.getOrDefault(node, new ArrayList<>())) {
indeg.put(adj, indeg.get(adj) - 1);
if (indeg.get(adj) == 0) {
qu.offer(adj);
}
}
}
vis = new HashSet<>();
List<Integer> ans = new ArrayList<>();
for (int node : topoSort) {
if (!vis.contains(node)) {
vis.add(node);
ans.add(node);
dfs(node, vis, graph);
}
}
return ans;
}
public static void main(String[] args) {
Solution obj = new Solution();
int[][] edges = {{0, 1}, {2, 1}, {3, 2}, {4, 3}};
List<Integer> ans = obj.solve(edges);
System.out.println(ans);
}
}
// This code is written by Sundaram
Python
# Python program of the above approach
from collections import defaultdict, deque
class Solution:
# Function to perform DFS
def dfs(self, node, vis, graph):
# add node to visited set
vis.add(node)
for adj in graph[node]:
if (adj not in vis):
self.dfs(adj, vis, graph)
def solve(self, edges):
graph = defaultdict(list)
# dictionary storing
# indegrees of node
indeg = defaultdict(int)
# array to store topological
# sorting of the array
topo_sort = []
vis = set()
for (u, v) in edges:
graph[u].append(v)
# count indegree of each node
indeg[v] += 1
qu = deque()
for u in graph:
# add to ququ ,if indegree
# of node u is 0
if(indeg[u] == 0):
qu.append(u)
# Run till queue is not empty
while(qu):
node = qu.popleft()
# add node to topo_sort
topo_sort.append(node)
# traverse adj nodes
for adj in graph[node]:
# decrement count of indegree
# of each adj node by 1
indeg[adj] -= 1
# if count becomes 0, then
# add adj to qu
if (indeg[adj] == 0):
qu.append(adj)
vis = set()
ans = []
# Take each node from topo_sort
for node in topo_sort:
# check if node is visited
if (node not in vis):
vis.add(node)
ans.append(node)
# Mark all the reachable
# nodes as visited
self.dfs(node, vis, graph)
# finally return ans
return (ans)
obj = Solution()
edges = [[0, 1], [2, 1], [3, 2], [4, 3]]
ans = obj.solve(edges)
print(" ".join(str(n) for n in ans))
C#
using System;
using System.Collections.Generic;
using System.Linq;
public class Solution {
// Function to perform DFS
private void dfs(int node, HashSet<int> vis,
Dictionary<int, List<int> > graph)
{
vis.Add(node);
foreach(int adj in graph.GetValueOrDefault(
node, new List<int>()))
{
if (!vis.Contains(adj)) {
dfs(adj, vis, graph);
}
}
}
public List<int> Solve(int[][] edges)
{
Dictionary<int, List<int> > graph
= new Dictionary<int, List<int> >();
Dictionary<int, int> indeg
= new Dictionary<int, int>();
List<int> topoSort = new List<int>();
HashSet<int> vis = new HashSet<int>();
foreach(int[] edge in edges)
{
int u = edge[0];
int v = edge[1];
if (!graph.ContainsKey(u)) {
graph.Add(u, new List<int>());
}
graph[u].Add(v);
indeg[v] = indeg.GetValueOrDefault(v, 0) + 1;
}
Queue<int> qu = new Queue<int>();
foreach(int u in graph.Keys)
{
if (!indeg.ContainsKey(u)) {
qu.Enqueue(u);
}
}
while (qu.Count() != 0) {
int node = qu.Dequeue();
topoSort.Add(node);
foreach(int adj in graph.GetValueOrDefault(
node, new List<int>()))
{
indeg[adj] = indeg[adj] - 1;
if (indeg[adj] == 0) {
qu.Enqueue(adj);
}
}
}
vis = new HashSet<int>();
List<int> ans = new List<int>();
foreach(int node in topoSort)
{
if (!vis.Contains(node)) {
vis.Add(node);
ans.Add(node);
dfs(node, vis, graph);
}
}
return ans;
}
public static void Main()
{
Solution obj = new Solution();
int[][] edges
= { new int[] { 0, 1 }, new int[] { 2, 1 },
new int[] { 3, 2 }, new int[] { 4, 3 } };
List<int> ans = obj.Solve(edges);
Console.WriteLine(string.Join(", ", ans));
}
}
// This code is contrubuted by user_dtewbxkn77n
JavaScript
// Function to perform DFS
function dfs(node, vis, graph) {
vis.add(node);
for (const adj of graph[node] || []) {
if (!vis.has(adj)) {
dfs(adj, vis, graph);
}
}
}
class Solution {
solve(edges) {
const graph = {};
const indeg = {};
const topoSort = [];
const vis = new Set();
// Build graph and calculate indegree
for (const [u, v] of edges) {
if (!graph[u]) {
graph[u] = [];
}
graph[u].push(v);
indeg[v] = (indeg[v] || 0) + 1;
}
// Enqueue all nodes with 0 indegree
const qu = [];
for (const u of Object.keys(graph)) {
if (!indeg[u]) {
qu.push(u);
}
}
// Perform topological sort
while (qu.length) {
const node = qu.shift();
topoSort.push(node);
for (const adj of graph[node] || []) {
indeg[adj]--;
if (indeg[adj] === 0) {
qu.push(adj);
}
}
}
// Perform DFS on unvisited nodes in topoSort
vis.clear();
const ans = [];
for (const node of topoSort) {
if (!vis.has(node)) {
vis.add(node);
ans.push(node);
dfs(node, vis, graph);
}
}
return ans;
}
}
// Driver code
const obj = new Solution();
const edges = [
[0, 1],
[2, 1],
[3, 2],
[4, 3],
];
// Function call
const ans = obj.solve(edges);
console.log(ans.join(" "));
// This code is contributed by phasing17
Time Complexity: O(N)
Auxiliary Space: O(N)
Approach 2: The given problem can also be solved using the observation that vertices with in-degree 0 are the vertices that can not be reached from any other vertex. Hence, the idea is to find the indegree of each vertex and insert the vertices with in-degree 0 into the required set, as all the other vertices can be visited eventually.
Below is the implementation of the above approach:
C++
// C++ program of the above approach
#include <bits/stdc++.h>
using namespace std;
// Function to find smallest set
// of vertices from which the
// complete graph can be visited
vector<int> solve(vector<vector<int>>& edges)
{
map<int, int> graph;
// Dictionary storing
// indegree of nodes
map<int, int> indeg;
for(auto dt : edges)
{
graph[dt[0]] = dt[1];
// Count indegree of
// each node
indeg[dt[1]] += 1;
}
vector<int> ans;
for(auto it = graph.begin();
it != graph.end(); ++it)
{
// Add to ans, if indegree
// of node u is 0
if (!indeg.count(it->first))
ans.push_back(it->first);
}
// Return Ans
return ans;
}
// Driver code
int main()
{
vector<vector<int>> edges = { { 0, 1 }, { 2, 1 },
{ 3, 2 }, { 4, 3 } };
vector<int> ans = solve(edges);
for(auto dt : ans)
cout << dt << " ";
return 0;
}
// This code is contributed by rakeshsahni
Java
// Java program of the above approach
import java.util.*;
class GFG{
// Function to find smallest set
// of vertices from which the
// complete graph can be visited
static Vector<Integer> solve(int[][] edges)
{
HashMap<Integer,Integer> graph = new HashMap<Integer,Integer>();
// Dictionary storing
// indegree of nodes
HashMap<Integer,Integer> indeg = new HashMap<Integer,Integer>();
for(int dt[] : edges)
{
graph.put(dt[0], dt[1]);
// Count indegree of
// each node
if(indeg.containsKey(dt[1])) {
indeg.put(dt[1], indeg.get(dt[1])+1);
}
else
indeg.put(dt[1], 1);
}
Vector<Integer> ans = new Vector<Integer>();
for (Map.Entry<Integer,Integer> it : graph.entrySet())
{
// Add to ans, if indegree
// of node u is 0
if (!indeg.containsKey(it.getKey()))
ans.add(it.getKey());
}
// Return Ans
return ans;
}
// Driver code
public static void main(String[] args)
{
int[][]edges = { { 0, 1 }, { 2, 1 },
{ 3, 2 }, { 4, 3 } };
Vector<Integer> ans = solve(edges);
for(int dt : ans)
System.out.print(dt+ " ");
}
}
// This code is contributed by shikhasingrajput
Python
# Python program of the above approach
from collections import defaultdict
class Solution:
# Function to find smallest set
# of vertices from which the
# complete graph can be visited
def solve(self , edges):
graph = defaultdict(list)
# dictionary storing
# indegree of nodes
indeg = defaultdict(int)
for (u,v) in edges:
graph[u].append(v)
# count indegree of
# each node
indeg[v] +=1
ans = []
for u in graph:
# add to ans, if indegree
# of node u is 0
if(indeg[u] == 0):
ans.append(u)
# Return Ans
return (ans)
obj = Solution()
edges = [[0,1] , [2,1] , [3,2] , [4,3] ]
ans= obj.solve(edges)
print(" ".join(str(n) for n in ans))
C#
// C# program of the above approach
using System;
using System.Collections.Generic;
public class GFG {
// Function to find smallest set
// of vertices from which the
// complete graph can be visited
static List<int> solve(int[, ] edges)
{
Dictionary<int, int> graph
= new Dictionary<int, int>();
// Dictionary storing
// indegree of nodes
Dictionary<int, int> indeg
= new Dictionary<int, int>();
for (int k = 0; k < edges.GetLength(0); k++) {
int keys = edges[k, 0];
int values = edges[k, 1];
graph.Add(keys, values);
// Count indegree of
// each node
if (indeg.ContainsKey(values)) {
indeg[values] += 1;
}
else
indeg.Add(values, 1);
}
List<int> ans = new List<int>();
foreach(KeyValuePair<int, int> it in graph)
{
// Add to ans, if indegree
// of node u is 0
if (!indeg.ContainsKey(it.Key))
ans.Add(it.Key);
}
// Return Ans
return ans;
}
public static int[] GetRow(int[, ] matrix, int row)
{
var rowLength = matrix.GetLength(1);
var rowVector = new int[rowLength];
for (var i = 0; i < rowLength; i++)
rowVector[i] = matrix[row, i];
return rowVector;
}
// Driver code
public static void Main(String[] args)
{
int[, ] edges
= { { 0, 1 }, { 2, 1 }, { 3, 2 }, { 4, 3 } };
List<int> ans = solve(edges);
foreach(int dt in ans) Console.Write(dt + " ");
}
}
// This code is contributed by 29AjayKumar
JavaScript
// Javascript program of the above approach
// Function to find smallest set
// of vertices from which the
// complete graph can be visited
function solve(edges) {
let graph = new Map();
// Dictionary storing
// indegree of nodes
let indeg = new Map();
for (dt of edges) {
graph.set(dt[0], dt[1]);
// Count indegree of
// each node
if (indeg.has(dt[1])) {
indeg.set(dt[1], indeg.get(dt[1]) + 1);
}
else
indeg.set(dt[1], 1);
}
let ans = new Array();
for (key of graph.keys()) {
// Add to ans, if indegree
// of node u is 0
if (!indeg.has(key))
ans.push(key);
}
// Return Ans
return ans;
}
// Driver code
let edges = [[0, 1], [2, 1],
[3, 2], [4, 3]];
let ans = solve(edges);
for (dt of ans)
console.log(dt + " ");
// This code is contributed by Saurabh Jaiswal
Time Complexity: O(N)
Auxiliary Space: O(N)
Similar Reads
Topological Sorting
Topological sorting for Directed Acyclic Graph (DAG) is a linear ordering of vertices such that for every directed edge u-v, vertex u comes before v in the ordering.Note: Topological Sorting for a graph is not possible if the graph is not a DAG.Example:Input: V = 6, edges = [[2, 3], [3, 1], [4, 0],
10 min read
Kahn's algorithm for Topological Sorting
Given a Directed Acyclic Graph having V vertices and E edges, your task is to find any Topological Sorted order of the graph.Topological Sorted order: It is a linear ordering of vertices such that for every directed edge u -> v, where vertex u comes before v in the ordering.Example:Input: V=6 , E
9 min read
Topological Sort in different languages
Problems based on Topological Sort
All Topological Sorts of a Directed Acyclic Graph
Topological sorting for Directed Acyclic Graph (DAG) is a linear ordering of vertices such that for every directed edge uv, vertex u comes before v in the ordering. Topological Sorting for a graph is not possible if the graph is not a DAG. Given a DAG, print all topological sorts of the graph. For e
11 min read
Detect cycle in Directed Graph using Topological Sort
Given a Directed Graph consisting of N vertices and M edges and a set of Edges[][], the task is to check whether the graph contains a cycle or not using Topological sort. Topological sort of directed graph is a linear ordering of its vertices such that, for every directed edge U -> V from vertex
9 min read
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
8 min read
Topological Sort of a graph using departure time of vertex
Given a Directed Acyclic Graph (DAG), find Topological Sort of the graph. Topological sorting for Directed Acyclic Graph (DAG) is a linear ordering of vertices such that for every directed edge uv, vertex u comes before v in the ordering. Topological Sorting for a graph is not possible if the graph
9 min read
Smallest set of vertices to visit all nodes of the given Graph
Given a directed acyclic graph of N nodes, the task is to find the smallest set of vertices from which the complete graph can be visited.Examples:Â Input: Graph in the image belowOutput: 0 4Explanation: From vertex 0, the set of nodes that can be visited is {0 ,1}. Similarly, from vertex 4, {4, 3, 2}
12 min read
Minimum time taken by each job to be completed given by a Directed Acyclic Graph
Given a Directed Acyclic Graph having V vertices and E edges, where each edge {U, V} represents the Jobs U and V such that Job V can only be started only after completion of Job U. The task is to determine the minimum time taken by each job to be completed where each Job takes unit time to get compl
12 min read