Open In App

Find dependencies of each Vertex in a Directed Graph

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Share
Report issue
Report

Given a directed graph containing N vertices and M edges, the task is to find all the dependencies of each vertex in the graph and the vertex with the minimum dependency.
 

A directed graph (or digraph) is a set of nodes connected by edges, where the edges have a direction associated with them. 
For example, an arc (x, y) is considered to be directed from x to y, and the arc (y, x) is the inverted link. Y is a direct successor of x, and x is a direct predecessor of y. 
The dependency is the number of connections to different vertices which are dependent on the current vertex. 
 

Examples: 
 

Input: 
 

Output: 
Vertex 1 dependencies -> 2-> 3 
Vertex 2 dependencies -> 3-> 1 
Vertex 3 dependencies -> 1-> 2 
Node 1 has the minimum number of dependency of 2. 
Explanation: 
Vertex 1 is dependent on 2 and 3. 
Similarly, vertex 2 and 3 on (3, 1) and (1, 2) respectively. 
Therefore, the minimum number of dependency among all vertices is 2. 
Input: 
 

Output: 
Vertex 1 dependency -> 2-> 3-> 4-> 5-> 6 
Vertex 2 dependency -> 6 
Vertex 3 dependency -> 4-> 5-> 6 
Vertex 4 dependency -> 5-> 6 
Vertex 5 dependency -> 6 
Vertex 6 is not dependent on any vertex. 
Node 6 has the minimum dependency of 0 
Explanation: 
Vertex 1 is dependent on (3, 4, 5, 6, 7). Similarly, vertex 2 on (6), vertex 3 on (4, 5, 6), vertex 4 on (5, 6), vertex 5 on (6) and vertex 6 is not dependent on any. 
Therefore, the minimum number of dependency among all vertices is 0. 
 

 

Approach: The idea is to use depth-first search(DFS) to solve this problem. 
 

  • Get the directed graph as the input.
  • Perform the DFS on the graph and explore all the nodes of the graph.
  • While exploring the neighbours of the node, add 1 to count and finally return the count which signifies the number of dependencies.
  • Finally, find the node with the minimum number of dependencies.

Below is the implementation of the above approach:
 

CPP




// C++ program to find the
// dependency of each node
 
#include <bits/stdc++.h>
using namespace std;
 
// Defining the graph
class Graph {
 
    // Variable to store the
    // number of vertices
    int V;
 
    // Adjacency list
    list<int>* adjList;
 
    // Initializing the graph
public:
    Graph(int v)
    {
        V = v;
        adjList = new list<int>[V];
    }
 
    // Adding edges
    void addEdge(int u, int v,
                 bool bidir = true)
    {
        adjList[u].push_back(v);
        if (bidir) {
            adjList[u].push_back(v);
        }
    }
 
    // Performing DFS on each node
    int dfs(int src)
    {
        // Map is used to mark
        // the current node as visited
        map<int, bool> visited;
        vector<int> dependent;
        int count = 0;
 
        stack<int> s;
 
        // Push the current vertex
        // to the stack which
        // stores the result
        s.push(src);
 
        visited[src] = true;
 
        // Traverse through the vertices
        // until the stack is empty
        while (!s.empty()) {
            int n = s.top();
            s.pop();
 
            // Recur for all the vertices
            // adjacent to this vertex
            for (auto i : adjList[n]) {
 
                // If the vertices are
                // not visited
                if (!visited[i]) {
                    dependent.push_back(i + 1);
                    count++;
 
                    // Mark the vertex as
                    // visited
                    visited[i] = true;
 
                    // Push the current vertex to
                    // the stack which stores
                    // the result
                    s.push(i);
                }
            }
        }
 
        // If the vertex has 0 dependency
        if (!count) {
            cout << "Vertex " << src + 1
                 << " is not dependent on any vertex.\n";
            return count;
        }
 
        cout << "Vertex " << src + 1 << " dependency ";
        for (auto i : dependent) {
            cout << "-> " << i;
        }
        cout << "\n";
        return count;
    }
};
 
// Function to find the
// dependency of each node
void operations(int arr[][2],
                int n, int m)
{
    // Creating a new graph
    Graph g(n);
 
    for (int i = 0; i < m; i++) {
        g.addEdge(arr[i][0],
                  arr[i][1], false);
    }
 
    int ans = INT_MAX;
    int node = 0;
 
    // Iterating through the graph
    for (int i = 0; i < n; i++) {
        int c = g.dfs(i);
 
        // Finding the node with
        // minimum number of
        // dependency
        if (c < ans) {
            ans = c;
            node = i + 1;
        }
    }
    cout << "Node " << node
         << "has minimum dependency of "
         << ans;
}
 
// Driver code
int main()
{
    int n, m;
 
    n = 6, m = 6;
 
    // Defining the edges of the
    // graph
    int arr[][2] = { { 0, 1 },
                     { 0, 2 },
                     { 2, 3 },
                     { 4, 5 },
                     { 3, 4 },
                     { 1, 5 } };
 
    operations(arr, n, m);
 
    return 0;
}


Java




// Java program to find the
// dependency of each node
import java.util.*;
class Graph {
 
  // Variable to store the
  // number of vertices
  int V;
 
  // Adjacency list
  List<Integer>[] adjList;
 
  // Initializing the graph
  public Graph(int v)
  {
    V = v;
    adjList = new ArrayList[V];
    for (int i = 0; i < V; i++)
      adjList[i] = new ArrayList<>();
  }
 
  // Adding edges
  void addEdge(int u, int v, boolean bidir)
  {
    adjList[u].add(v);
    if (bidir)
      adjList[v].add(u);
  }
 
  // Performing DFS on each node
  int dfs(int src)
  {
    // Map is used to mark
    // the current node as visited
    Map<Integer, Boolean> visited = new HashMap<>();
    List<Integer> dependent = new ArrayList<>();
    int count = 0;
 
    Stack<Integer> s = new Stack<Integer>();
 
    // Push the current vertex
    // to the stack which
    // stores the result
    s.push(src);
 
    visited.put(src, true);
 
    // Traverse through the vertices
    // until the stack is empty
    while (!s.empty()) {
      int n = s.peek();
      s.pop();
 
      // Recur for all the vertices
      // adjacent to this vertex
      for (int i : adjList[n]) {
 
        // If the vertices are
        // not visited
        if (!visited.containsKey(i)) {
          dependent.add(i + 1);
          count++;
 
          // Mark the vertex as
          // visited
          visited.put(i, true);
 
          // Push the current vertex to
          // the stack which stores
          // the result
          s.push(i);
        }
      }
    }
 
    // If the vertex has 0 dependency
    if (count!=0) {
      System.out.print(
        "Vertex " + (src + 1)
        + " is not dependent on any vertex.\n");
      return count;
    }
 
    System.out.print("Vertex " + (src + 1)
                     + " dependency ");
    for (int i : dependent) {
      System.out.print("-> " + i);
    }
    System.out.println();
    return count;
  }
}
 
class GFG {
 
  // Function to find the
  // dependency of each node
  static void operations(int arr[][], int n, int m)
  {
    // Creating a new graph
    Graph g = new Graph(n);
 
    for (int i = 0; i < m; i++) {
      g.addEdge(arr[i][0], arr[i][1], false);
    }
 
    int ans = Integer.MAX_VALUE;
    int node = 0;
 
    // Iterating through the graph
    for (int i = 0; i < n; i++) {
      int c = g.dfs(i);
 
      // Finding the node with
      // minimum number of
      // dependency
      if (c < ans) {
        ans = c;
        node = i + 1;
      }
    }
    System.out.print("Node " + node
                     + "has minimum dependency of "
                     + ans);
  }
 
  // Driver code
  public static void main(String[] args)
  {
    int n, m;
 
    n = 6;
    m = 6;
 
    // Defining the edges of the
    // graph
    int arr[][] = { { 0, 1 }, { 0, 2 }, { 2, 3 },
                   { 4, 5 }, { 3, 4 }, { 1, 5 } };
 
    operations(arr, n, m);
  }
}
 
// This code is contributed by ishankhandelwals.


Python3




# Python3 program to find the
# dependency of each node
 
# Adding edges
def addEdge(u, v, bidir = True):
    global adjList
    adjList[u].append(v)
    if (bidir):
        adjList[u].append(v)
 
# Performing DFS on each node
def dfs(src):
    global adjList, V
     
    # Map is used to mark
    # the current node as visited
    visited = [False for i in range(V+1)]
    dependent = []
    count = 0
    s = []
 
    # Push the current vertex
    # to the stack which
    # stores the result
    s.append(src)
    visited[src] = True
 
    # Traverse through the vertices
    # until the stack is empty
    while (len(s) > 0):
        n = s[-1]
        del s[-1]
 
        # Recur for all the vertices
        # adjacent to this vertex
        for i in adjList[n]:
 
            # If the vertices are
            # not visited
            if (not visited[i]):
                dependent.append(i + 1)
                count += 1
 
                # Mark the vertex as
                # visited
                visited[i] = True
 
                # Push the current vertex to
                # the stack which stores
                # the result
                s.append(i)
 
    # If the vertex has 0 dependency
    if (not count):
        print("Vertex ", src + 1,
              " is not dependent on any vertex.")
        return count
 
    print("Vertex ",src + 1," dependency ",end="")
    for i in dependent:
        print("-> ", i, end = "")
    print()
    return count
 
# Function to find the
# dependency of each node
def operations(arr, n, m):
   
    # Creating a new graph
    global adjList
    for i in range(m):
        addEdge(arr[i][0], arr[i][1], False)
    ans = 10**18
    node = 0
 
    # Iterating through the graph
    for i in range(n):
        c = dfs(i)
 
        # Finding the node with
        # minimum number of
        # dependency
        if (c < ans):
            ans = c
            node = i + 1
    print("Node", node, "has minimum dependency of ", ans)
 
# Driver code
if __name__ == '__main__':
    V = 6
    adjList = [[] for i in range(V+1)]
    n, m = 6, 6
 
 
    # Defining the edges of the
    # graph
    arr = [ [ 0, 1 ],
             [ 0, 2 ],
             [ 2, 3 ],
             [ 4, 5 ],
             [ 3, 4 ],
             [ 1, 5 ] ]
 
    operations(arr, n, m)
 
    # This code is contributed by mohit kumar 29.


C#




// C# program to find the
// dependency of each node
using System;
using System.Collections.Generic;
 
// Defining the graph
public class Graph {
  // Variable to store the
  // number of vertices
  int V;
 
  // Adjacency list
  List<int>[] adjList;
 
  // Initializing the graph
  public Graph(int v)
  {
    V = v;
    adjList = new List<int>[ V ];
  }
 
  // Adding edges
  public void addEdge(int u, int v, bool bidir = true)
  {
    adjList[u].Add(v);
    if (bidir) {
      adjList[u].Add(v);
    }
  }
 
  // Performing DFS on each node
  public int dfs(int src)
  {
    // Map is used to mark
    // the current node as visited
    Dictionary<int, bool> visited
      = new Dictionary<int, bool>();
    List<int> dependent = new List<int>();
    int count = 0;
 
    Stack<int> s = new Stack<int>();
 
    // Push the current vertex
    // to the stack which
    // stores the result
    s.Push(src);
 
    visited.Add(src, true);
 
    // Traverse through the vertices
    // until the stack is empty
    while (s.Count != 0) {
      int n = s.Pop();
 
      // Recur for all the vertices
      // adjacent to this vertex
      foreach(var i in adjList[n])
      {
 
        // If the vertices are
        // not visited
        if (visited.ContainsKey(i) == false) {
          dependent.Add(i + 1);
          count++;
 
          // Mark the vertex as
          // visited
          visited.Add(i, true);
 
          // Push the current vertex to
          // the stack which stores
          // the result
          s.Push(i);
        }
      }
    }
 
    // If the vertex has 0 dependency
    if (count == 0) {
      Console.WriteLine(
        "Vertex " + (src + 1)
        + " is not dependent on any vertex.");
      return count;
    }
 
    Console.Write("Vertex " + (src + 1)
                  + " dependency ");
    foreach(var i in dependent)
    {
      Console.Write("-> " + i);
    }
    Console.WriteLine();
    return count;
  }
}
 
// Function to find the
// dependency of each node
public void operations(int[, ] arr, int n, int m)
{
  // Creating a new graph
  Graph g = new Graph(n);
 
  for (int i = 0; i < m; i++) {
    g.addEdge(arr[i, 0], arr[i, 1], false);
  }
 
  int ans = int.MaxValue;
  int node = 0;
 
  // Iterating through the graph
  for (int i = 0; i < n; i++) {
    int c = g.dfs(i);
 
    // Finding the node with
    // minimum number of
    // dependency
    if (c < ans) {
      ans = c;
      node = i + 1;
    }
  }
  Console.WriteLine("Node " + node
                    + "has minimum dependency of " + ans);
}
 
// Driver code
public static void Main()
{
  int n, m;
 
  n = 6;
  m = 6;
 
  // Defining the edges of the
  // graph
  int[, ] arr
    = new int[, ] { { 0, 1 }, { 0, 2 }, { 2, 3 },
                   { 4, 5 }, { 3, 4 }, { 1, 5 } };
 
  operations(arr, n, m);
}
 
// This code is contributed by ishankhandelwals.


Javascript




// Javascript code
 
// Defining the graph
class Graph {
  // Variable to store the
  // number of vertices
  constructor(v){
      this.V = v;
      this.adjList = new Array(this.V).fill(new Array());
  }
 
  // Adding edges
  addEdge(u, v, bidir = true) {
      this.adjList[u].push(v);
      if (bidir) {
          this.adjList[v].push(u);
      }
  }
 
  // Performing DFS on each node
  dfs(src) {
      // Map is used to mark
      // the current node as visited
      let visited = new Map();
      let dependent = [];
      let count = 0;
 
      let s = [];
 
      // Push the current vertex
      // to the stack which
      // stores the result
      s.push(src);
 
      visited.set(src, true);
 
      // Traverse through the vertices
      // until the stack is empty
      while (s.length > 0) {
          let n = s.pop();
 
          // Recur for all the vertices
          // adjacent to this vertex
          this.adjList[n].forEach(i => {
 
              // If the vertices are
              // not visited
              if (!visited.get(i)) {
                  dependent.push(i + 1);
                  count++;
 
                  // Mark the vertex as
                  // visited
                  visited.set(i, true);
 
                  // Push the current vertex to
                  // the stack which stores
                  // the result
                  s.push(i);
              }
          });
      }
 
      // If the vertex has 0 dependency
      if (!count) {
          console.log(`Vertex ${src + 1} is not dependent on any vertex.`);
          return count;
      }
 
      console.log(`Vertex ${src + 1} dependency `);
      dependent.forEach(i => {
          console.log(`-> ${i}`);
      });
 
      return count;
  }
}
 
// Function to find the
// dependency of each node
function operations(arr, n, m) {
  // Creating a new graph
  let g = new Graph(n);
 
  for (let i = 0; i < m; i++) {
      g.addEdge(arr[i][0], arr[i][1], false);
  }
 
  let ans = Number.MAX_VALUE;
  let node = 0;
 
  // Iterating through the graph
  for (let i = 0; i < n; i++) {
      let c = g.dfs(i);
 
      // Finding the node with
      // minimum number of
      // dependency
      if (c < ans) {
          ans = c;
          node = i + 1;
      }
  }
  console.log(`Node ${node} has minimum dependency of ${ans}`);
}
 
// Driver code
(function () {
  let n = 6, m = 6;
 
  // Defining the edges of the
  // graph
  let arr = [
      [0, 1],
      [0, 2],
      [2, 3],
      [4, 5],
      [3, 4],
      [1, 5]
  ];
 
  operations(arr, n, m);
})();
 
// This code is contributed by ishankhandelwals.


Output: 

Vertex 1 dependency -> 2-> 3-> 4-> 5-> 6
Vertex 2 dependency -> 6
Vertex 3 dependency -> 4-> 5-> 6
Vertex 4 dependency -> 5-> 6
Vertex 5 dependency -> 6
Vertex 6 is not dependent on any vertex.
Node 6has minimum dependency of 0

 

Time Complexity: O(V+E),The time complexity of the above program is O(V+E) where V is the number of vertices and E is the number of edges. We iterate through the graph and perform Depth First Search on each node. This takes O(V+E) time to complete.

Space Complexity: O(V),The space complexity of the above program is O(V). We are creating an adjacency list for the graph which takes O(V) space. We also create a stack and a map to keep track of the nodes which are visited. This takes O(V) space.



Last Updated : 02 Mar, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads