Open In App

# Count of nodes accessible from all other nodes of Graph

Given a directed graph with N nodes and M edges in array V[], the task is to find the number of nodes that are accessible from all other nodes i.e., they have at least one path from all other nodes.

Examples:

Input: N = 5 and M = 5, V = [[1, 2], [2, 3], [3, 4], [4, 3], [5, 4]]
Output: 2
Explanation:
We can look closely after forming graph
than captain america only can hide in a
room 3 and 4 because they are the only room
which have gates through them. So,

Input: N = 2, M = 1, V = [[1, 2]]
Output: 1

Approach: This problem can be solved using Kosaraju’s Algorithm to find the count of Strongly Connected Components based on the following idea:

All the nodes in a single strongly connected component are reachable from any other node of that component. If each connected component is considered as a node of the graph then there are the following cases:

• The connected components are disconnected. So, more than one component will have outdegree greater than 0. In this case, no node is reachable from all other nodes.
• There is only one connected component. This time all the nodes are reachable from all other nodes.
• There are more than one connected components and only one node has outdegree equal to 0. In this case only that node is reachable from all other nodes.

Follow the steps mentioned below to implement the above idea:

• Find all strongly connected components of the given graph
• Create a new graph in which each strongly connected component is considered as a single node. (let’s say this graph is grrrr)
• Find number of nodes in grrrr having outdegree ==0 (let this number is x1)
• If x1 > 1 then answer is 0 because this suggests that some nodes are not reachable from others or some components are disconnected.
• If x1 = 0 then answer is also 0.
• So  exist only when x1 = 1 and the answer is equal to the number of nodes in the strongly connected component having outdegree = 0 in graph grrrr.

Below is the implementation of the above approach.

## C++

 `// C++ code to implement the approach` `#include ``using` `namespace` `std;` `vector<``int``> adj[100001];``vector<``int``> transpose[100001];``int` `vis[100001], parent[100001], no[100001];` `// Function to form the components``void` `dfs(``int` `node, vector<``int``> adj[], stack<``int``>& st,``         ``int` `vis[])``{``    ``vis[node] = 1;``    ``for` `(``int` `it : adj[node]) {``        ``if` `(vis[it] == 0) {``            ``dfs(it, adj, st, vis);``        ``}``    ``}``    ``st.push(node);``}` `// Function to run dfs in the``// transpose adjacency to get``// the strongly connected components``void` `dfs_(``int` `node, vector<``int``> transpose[], ``int` `vis[],``          ``int` `par)``{``    ``vis[node] = 1;``    ``parent[node] = par;``    ``no[par]++;``    ``for` `(``int` `it : transpose[node]) {``        ``if` `(vis[it] == 0) {``            ``dfs_(it, transpose, vis, par);``        ``}``    ``}``}` `// Function to form the new graph using``// the strongly connected components``void` `dfs__(``int` `node, ``int` `vis[], vector<``int``> adj[],``           ``vector<``int``> adjn[], ``int` `parent[])``{``    ``vis[node] = 1;``    ``for` `(``int` `it : adj[node]) {``        ``int` `par1 = parent[node];``        ``int` `par2 = parent[it];``        ``if` `(par1 == par2) {``            ``continue``;``        ``}``        ``adjn[par1].push_back(par2);``        ``if` `(vis[it] == 0) {``            ``dfs__(it, vis, adj, adjn, parent);``        ``}``    ``}``}` `// Function to find the total number``// of reachable nodes``int` `countReachables(``int` `N, ``int` `M, vector > V)``{``    ``for` `(``int` `i = 0; i < M; i++) {``        ``adj[V[i].first - 1].push_back(V[i].second - 1);``    ``}``    ``memset``(vis, 0, ``sizeof``(vis));` `    ``// Stack to store the components``    ``stack<``int``> st;``    ``for` `(``int` `i = 0; i < N; i++) {``        ``if` `(vis[i] == 0) {``            ``dfs(i, adj, st, vis);``        ``}``    ``}` `    ``// Transpose the graph and perform the second DFS``    ``// traversal``    ``for` `(``int` `i = 0; i < N; i++) {``        ``for` `(``int` `it : adj[i]) {``            ``transpose[it].push_back(i);``        ``}``    ``}``    ``memset``(vis, 0, ``sizeof``(vis));``    ``memset``(parent, 0, ``sizeof``(parent));``    ``memset``(no, 0, ``sizeof``(no));``    ``int` `par = 0;``    ``while` `(!st.empty()) {``        ``int` `node = st.top();``        ``st.pop();``        ``if` `(vis[node] == 0) {``            ``dfs_(node, transpose, vis, par);``            ``par++;``        ``}``    ``}` `    ``// Adjacency matrix to represent the graph``    ``// where each node is a strongly connected component``    ``vector<``int``> adjn[100001];``    ``memset``(vis, 0, ``sizeof``(vis));``    ``for` `(``int` `i = 0; i < N; i++) {``        ``if` `(vis[i] == 0) {``            ``dfs__(i, vis, adj, adjn, parent);``        ``}``    ``}``    ``// Check nodes with outdegree 0``    ``int` `outDegree = 0;``    ``for` `(``int` `i = 0; i < par; i++) {``        ``if` `(adjn[i].size() == 0) {``            ``outDegree++;``        ``}``    ``}` `    ``// Decide the count based on the conditions``    ``if` `(outDegree > 1 || outDegree == 0) {``        ``return` `0;``    ``}``    ``else` `{``        ``for` `(``int` `i = 0; i < par; i++) {``            ``if` `(adjn[i].size() == 0) {``                ``return` `no[i];``            ``}``        ``}``        ``return` `0;``    ``}``}``// Driver code``int` `main()``{``    ``int` `N = 5;``    ``int` `M = 5;``    ``int` `V[M + 1][2] = {``        ``{ 1, 2 }, { 2, 3 }, { 3, 4 }, { 4, 3 }, { 5, 4 }``    ``};` `    ``vector > V_vec;``    ``for` `(``int` `i = 0; i < M; i++) {``        ``V_vec.push_back(make_pair(V[i][0], V[i][1]));``    ``}``    ``// Function call``    ``int` `ans = countReachables(N, M, V_vec);``    ``cout << ans;``    ``return` `0;``}`

## Java

 `// Java code to implement the approach` `import` `java.io.*;``import` `java.util.*;` `class` `GFG {` `    ``// Function to form the components``    ``private` `static` `void``    ``dfs(``int` `node, ArrayList > adj,``        ``Stack st, ``int``[] vis)``    ``{``        ``vis[node] = ``1``;``        ``for` `(Integer it : adj.get(node)) {``            ``if` `(vis[it] == ``0``) {``                ``dfs(it, adj, st, vis);``            ``}``        ``}``        ``st.push(node);``    ``}` `    ``// Function to run dfs in the``    ``// transpose adjacency to get``    ``// the strongly connected components``    ``private` `static` `void``    ``dfs_(``int` `node, ArrayList > transpose,``         ``int``[] vis, ``int` `par, ``int``[] parent, ``int``[] no)``    ``{``        ``vis[node] = ``1``;` `        ``parent[node] = par;``        ``no[par]++;``        ``for` `(Integer it : transpose.get(node)) {``            ``if` `(vis[it] == ``0``) {``                ``dfs_(it, transpose, vis, par, parent, no);``            ``}``        ``}``    ``}` `    ``// Function to form the new graph using``    ``// the strongly connected components``    ``private` `static` `void``    ``dfs__(``int` `node, ``int``[] vis,``          ``ArrayList > adj,``          ``ArrayList > adjn, ``int``[] parent)``    ``{``        ``vis[node] = ``1``;``        ``for` `(Integer it : adj.get(node)) {``            ``int` `par1 = parent[node];``            ``int` `par2 = parent[it];``            ``if` `(par1 == par2) {``                ``continue``;``            ``}``            ``adjn.get(par1).add(par2);``            ``if` `(vis[it] == ``0``) {``                ``dfs__(it, vis, adj, adjn, parent);``            ``}``        ``}``    ``}` `    ``// Function to find the total number``    ``// of reachable nodes``    ``public` `static` `int` `countReachables(``int` `N, ``int` `M,``                                      ``int` `V[][])``    ``{``        ``ArrayList > adj``            ``= ``new` `ArrayList<>();``        ``for` `(``int` `i = ``0``; i < N; i++) {``            ``adj.add(``new` `ArrayList<>());``        ``}` `        ``// Generate the adjacency matrix``        ``for` `(``int` `i = ``0``; i < M; i++) {``            ``adj.get(V[i][``0``] - ``1``).add(V[i][``1``] - ``1``);``        ``}``        ``int``[] vis = ``new` `int``[N];` `        ``// Stack to store the components``        ``Stack st = ``new` `Stack<>();``        ``for` `(``int` `i = ``0``; i < N; i++) {``            ``if` `(vis[i] == ``0``) {``                ``dfs(i, adj, st, vis);``            ``}``        ``}``        ``ArrayList > transpose``            ``= ``new` `ArrayList<>();``        ``for` `(``int` `i = ``0``; i < N; i++) {``            ``transpose.add(``new` `ArrayList<>());``            ``vis[i] = ``0``;``        ``}` `        ``// Transpose adjacency matrix``        ``for` `(``int` `i = ``0``; i < M; i++) {``            ``transpose.get(V[i][``1``] - ``1``).add(V[i][``0``] - ``1``);``        ``}``        ``int``[] parent = ``new` `int``[N];``        ``int` `par = ``0``;``        ``int``[] no = ``new` `int``[N];``        ``while` `(!st.isEmpty()) {``            ``int` `node = st.pop();``            ``if` `(vis[node] == ``0``) {``                ``dfs_(node, transpose, vis, par, parent, no);``                ``par++;``            ``}``        ``}` `        ``// Adjacency matrix to represent the graph``        ``// where each node is a strongly connected component``        ``ArrayList > adjn``            ``= ``new` `ArrayList<>();``        ``for` `(``int` `i = ``0``; i < par; i++) {``            ``adjn.add(``new` `ArrayList<>());``        ``}``        ``Arrays.fill(vis, ``0``);``        ``for` `(``int` `i = ``0``; i < N; i++) {``            ``if` `(vis[i] == ``0``) {``                ``dfs__(i, vis, adj, adjn, parent);``            ``}``        ``}` `        ``// Check nodes with outdegree 0``        ``int` `outDegree = ``0``;``        ``for` `(``int` `i = ``0``; i < par; i++) {``            ``if` `(adjn.get(i).size() == ``0``) {``                ``outDegree++;``            ``}``        ``}` `        ``// Decide the count based on the conditions``        ``if` `(outDegree > ``1` `|| outDegree == ``0``) {``            ``return` `0``;``        ``}``        ``else` `{``            ``for` `(``int` `i = ``0``; i < par; i++) {``                ``if` `(adjn.get(i).size() == ``0``) {``                    ``return` `no[i];``                ``}``            ``}``        ``}``        ``return` `-``1``;``    ``}` `    ``// Driver code``    ``public` `static` `void` `main(String[] args)``    ``{``        ``int` `N = ``5``;``        ``int` `M = ``5``;``        ``int` `V[][] = ``new` `int``[M + ``1``][``2``];` `        ``V[``0``][``0``] = ``1``;``        ``V[``0``][``1``] = ``2``;``        ``V[``1``][``0``] = ``2``;``        ``V[``1``][``1``] = ``3``;``        ``V[``2``][``0``] = ``3``;``        ``V[``2``][``1``] = ``4``;``        ``V[``3``][``0``] = ``4``;``        ``V[``3``][``1``] = ``3``;``        ``V[``4``][``0``] = ``5``;``        ``V[``4``][``1``] = ``4``;` `        ``// Function call``        ``int` `ans = countReachables(N, M, V);``        ``System.out.println(ans);``    ``}``}`

## Python3

 `from` `collections ``import` `defaultdict``from` `typing ``import` `List``, ``Tuple` `def` `countReachables(N: ``int``, M: ``int``, V: ``List``[``Tuple``[``int``, ``int``]]) ``-``> ``int``:``  ``# First DFS traversal``  ``# Create an adjacency list representation of the graph``  ``# Visit all nodes and push the node to the stack when all its children have been visited``    ``def` `dfs(node: ``int``, adj: ``List``[``List``[``int``]], st: ``list``, vis: ``List``[``int``]):``        ``vis[node] ``=` `1``        ``for` `it ``in` `adj[node]:``            ``if` `vis[it] ``=``=` `0``:``                ``dfs(it, adj, st, vis)``        ``st.append(node)``        ` `  ``# Second DFS traversal``  ``# Transpose the graph and visit all the nodes in the order they were pushed to the stack in the first DFS traversal``  ``# Record the number of nodes in each strongly connected component``  ``# Record the parent of each node in the DFS tree``    ``def` `dfs_(node: ``int``, transpose: ``List``[``List``[``int``]], vis: ``List``[``int``], par: ``int``, parent: ``List``[``int``], no: ``List``[``int``]):``        ``vis[node] ``=` `1``        ``parent[node] ``=` `par``        ``no[par] ``+``=` `1``        ``for` `it ``in` `transpose[node]:``            ``if` `vis[it] ``=``=` `0``:``                ``dfs_(it, transpose, vis, par, parent, no)``  ``# Third DFS traversal``  ``# Create a new graph that represents the strongly connected components``  ``# Visit all the nodes in the original graph in the order they were pushed to the stack in the first DFS traversal``  ``# If two nodes are in the same strongly connected component, skip them``  ``# If two nodes are in different strongly connected components, add an edge from the component of the first node to the component of the second node``    ``def` `dfs__(node: ``int``, vis: ``List``[``int``], adj: ``List``[``List``[``int``]], adjn: ``List``[``List``[``int``]], parent: ``List``[``int``]):``        ``vis[node] ``=` `1``        ``for` `it ``in` `adj[node]:``            ``par1 ``=` `parent[node]``            ``par2 ``=` `parent[it]``            ``if` `par1 ``=``=` `par2:``                ``continue``            ``adjn[par1].append(par2)``            ``if` `vis[it] ``=``=` `0``:``                ``dfs__(it, vis, adj, adjn, parent)``                ` `   ``# Convert the list of edges to an adjacency list``    ``adj ``=` `defaultdict(``list``)``    ``for` `i ``in` `range``(M):``        ``adj[V[i][``0``]``-``1``].append(V[i][``1``]``-``1``)``    ``vis ``=` `[``0``] ``*` `N` `    ``st ``=` `[]``    ``for` `i ``in` `range``(N):``        ``if` `vis[i] ``=``=` `0``:``            ``dfs(i, adj, st, vis)``            ` `    ``# Transpose the graph and perform the second DFS traversal``    ``transpose ``=` `defaultdict(``list``)``    ``for` `i ``in` `range``(N):``        ``transpose[V[i][``1``]``-``1``].append(V[i][``0``]``-``1``)``    ``vis ``=` `[``0``] ``*` `N``    ``parent ``=` `[``0``] ``*` `N``    ``par ``=` `0``    ``no ``=` `[``0``] ``*` `N``    ``while` `st:``        ``node ``=` `st.pop()``        ``if` `vis[node] ``=``=` `0``:``            ``dfs_(node, transpose, vis, par, parent, no)``            ``par ``+``=` `1``            ` `    ``# Create a new graph``    ``adjn ``=` `defaultdict(``list``)``    ``vis ``=` `[``0``] ``*` `N``    ``for` `i ``in` `range``(N):``        ``if` `vis[i] ``=``=` `0``:``            ``dfs__(i, vis, adj, adjn, parent)``    ` `    ``outDegree ``=` `0``    ``for` `i ``in` `range``(par):``        ``if` `len``(adjn[i]) ``=``=` `0``:``            ``outDegree ``+``=` `1``    ``if` `outDegree > ``1` `or` `outDegree ``=``=` `0``:``        ``return` `0``    ``else``:``        ``for` `i ``in` `range``(par):``            ``if` `len``(adjn[i]) ``=``=` `0``:``                ``return` `no[i]``        ``return` `0` `if` `__name__ ``=``=` `"__main__"``:``    ``N ``=` `5``    ``M ``=` `5``    ``V ``=` `[[``1``, ``2``], [``2``, ``3``], [``3``, ``4``], [``4``, ``3``], [``5``, ``4``]]` `    ``# Function call``    ``ans ``=` `countReachables(N, M, V)``    ``print``(ans)`

## Javascript

 `// This function takes a node and an adjacency list, and performs DFS starting at the node.``// It marks all visited nodes in the vis array and pushes the nodes onto the stack in the order they are visited.``function` `countReachables(N, M, V) {``    ``function` `dfs(node, adj, st, vis) {``        ``vis[node] = 1;``        ``for` `(let it of adj[node]) {``            ``if` `(vis[it] === 0) {``                ``dfs(it, adj, st, vis);``            ``}``        ``}``        ``st.push(node);``    ``}` `// This function performs transpose of the graph to determine the strongly connected components (SCCs).``// marks all visited nodes in the vis array and sets the parent and size arrays for each SCC.` `    ``function` `dfs_(node, transpose, vis, par, parent, no) {``        ``vis[node] = 1;``        ``parent[node] = par;``        ``no[par] += 1;``        ``for` `(let it of transpose[node]) {``            ``if` `(vis[it] === 0) {``                ``dfs_(it, transpose, vis, par, parent, no);``            ``}``        ``}``    ``}` `// This function performs build a new graph where each node represents an SCC and there is a directed edge between SCCs if there is a directed edge between any nodes in the SCCs.``    ``function` `dfs__(node, vis, adj, adjn, parent) {``        ``vis[node] = 1;``        ``for` `(let it of adj[node]) {``            ``let par1 = parent[node];``            ``let par2 = parent[it];``            ``if` `(par1 === par2) {``                ``continue``;``            ``}``            ``adjn[par1].push(par2);``            ``if` `(vis[it] === 0) {``                ``dfs__(it, vis, adj, adjn, parent);``            ``}``        ``}``    ``}``    ` `// Creates an adjacency list for the graph and performs the first DFS to fill the stack.` `    ``let adj = ``new` `Array(N).fill(0).map(() => []);``    ``for` `(let i = 0; i < M; i++) {``        ``adj[V[i][0] - 1].push(V[i][1] - 1);``    ``}``    ``let vis = ``new` `Array(N).fill(0);` `    ``let st = [];``    ``for` `(let i = 0; i < N; i++) {``        ``if` `(vis[i] === 0) {``            ``dfs(i, adj, st, vis);``        ``}``    ``}` `// Creates the transpose of the graph and performs the second DFS to determine SCCs and set parent and size arrays.``    ``let transpose = ``new` `Array(N).fill(0).map(() => []);``    ``for` `(let i = 0; i < N; i++) {``        ``transpose[V[i][1] - 1].push(V[i][0] - 1);``    ``}``    ``vis = ``new` `Array(N).fill(0);``    ``let parent = ``new` `Array(N).fill(0);``    ``let par = 0;``    ``let no = ``new` `Array(N).fill(0);``    ``while` `(st.length > 0) {``        ``let node = st.pop();``        ``if` `(vis[node] === 0) {``            ``dfs_(node, transpose, vis, par, parent, no);``            ``par++;``        ``}``    ``}``    ` `// Creates a new adjacency list for the SCC graph and performs the third DFS to build``    ``let adjn = ``new` `Array(N).fill(0).map(() => []);``    ``vis = ``new` `Array(N).fill(0);``    ``for` `(let i = 0; i < N; i++) {``        ``if` `(vis[i] === 0) {``            ``dfs__(i, vis, adj, adjn, parent);``        ``}``    ``}` `    ``let outDegree = 0;``    ``for``(let i = 0; i < par; i++) {``      ``if``(adjn[i].length == 0) {``         ``outDegree += 1;``     ``}``   ``}``   ``if``(outDegree > 1 || outDegree == 0) {``      ``return` `0;``   ``} ``else` `{``    ``for``(let i = 0; i < par; i++) {``        ``if``(adjn[i].length == 0) {``            ``return` `no[i];``        ``}``    ``}``}``}`  `let N = 5;``let M = 5;``let V = [[1, 2], [2, 3], [3, 4], [4, 3], [5, 4]];` `// Function call``let ans = countReachables(N, M, V);``console.log(ans);`

Output

`2`

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