Count of simple paths starting from source node
Given an undirected graph with N nodes and M edges in the form of array edg[][2], the task is to count all simple paths (paths without repeated vertices) from source node 1 in the given graph.
Examples:
Input: N = 4, edg[][2] = {{1, 2}, {2, 3}}
Output: 3
Explanation:
- path 1: 1
- path 2: 1 -> 2
- path 3: 1 -> 2 -> 3
Input: N = 4, edg[][2] = {{1, 2}, {1, 3}, {1, 4}, {2, 3}, {2, 4}, {3 4}}
Output: 16
Approach: To solve the problem follow the below idea:
The idea is to use recursion to traverse the graph starting from the source node and keep track of visited nodes and increment the counter for each path found. Traverse unvisited neighbors, and unmarks visited nodes so that multiple paths can be explored. Returns the total count of simple paths found.
Below are the steps for the above approach:
- Declare adjacency list adj[N + 1] and iterate on all M edges and fill adjacency list.
- Initialize a visited array of size N+1 with 0, vis[N + 1].
- Declare a variable say ans = 0.
- Create recursive function recur(), mark the current node visited and increment the ans by 1 and traverse its unvisited neighbors.
- When exiting the current node, unmark the node from the visited array.
- Return the variable ans.
Below is the implementation of the above approach:
C++
// C++ code to implement the approach #include <bits/stdc++.h> using namespace std; // recursive function void recur( int v, int & ans, vector<vector< int > >& adj, vector< int >& vis) { // Marking current node visited vis[v] = 1; // Incrementing the counter ans++; // Traversing for unvisited neighbors for ( auto & u : adj[v]) { if (!vis[u]) { recur(u, ans, adj, vis); } } // Unmarking for counting all simple // paths vis[v] = 0; } // Function to count number of simple // paths from given source node 1 int isPossible( int N, int edg[][2], int M) { // Initializing adjacency list vector<vector< int > > adj(N + 1); // Filling adjacency List for ( int i = 0; i < M; i++) { adj[edg[i][0]].push_back(edg[i][1]); adj[edg[i][1]].push_back(edg[i][0]); } // Visited array for recursion vector< int > vis(N + 1, 0); // Counter initialized to zero int ans = 0; // Calling dfs function recur(1, ans, adj, vis); // Returning answer return ans; } // Driver Code int main() { // Input 1 int N = 4, edg[][2] = { { 1, 2 }, { 2, 3 } }; int M = 2; // Function Call cout << isPossible(N, edg, M) << endl; return 0; } |
Java
// java code to implement the approach import java.io.*; import java.util.*; class GFG { // recursive function static void recur( int v, int [] ans, ArrayList<ArrayList<Integer> > adj, int [] vis) { // Marking current node visited vis[v] = 1 ; // Incrementing the counter ans[ 0 ]++; // Traversing for unvisited neighbors for ( int u : adj.get(v)) { if (vis[u] == 0 ) { recur(u, ans, adj, vis); } } // Unmarking for counting all simple paths vis[v] = 0 ; } // Function to count number of simple paths from given // source node 1 static int isPossible( int N, int [][] edg, int M) { // Initializing adjacency list ArrayList<ArrayList<Integer> > adj = new ArrayList<>(); for ( int i = 0 ; i <= N; i++) { adj.add( new ArrayList<Integer>()); } // Filling adjacency List for ( int i = 0 ; i < M; i++) { adj.get(edg[i][ 0 ]).add(edg[i][ 1 ]); adj.get(edg[i][ 1 ]).add(edg[i][ 0 ]); } // Visited array for recursion int [] vis = new int [N + 1 ]; // Counter initialized to zero int [] ans = { 0 }; // Calling dfs function recur( 1 , ans, adj, vis); // Returning answer return ans[ 0 ]; } public static void main(String[] args) { // Input 1 int N = 4 ; int [][] edg = { { 1 , 2 }, { 2 , 3 } }; int M = 2 ; // Function Call System.out.println(isPossible(N, edg, M)); } } // This code is contributed by lokesh. |
Python3
# Python code to implement the approach # Recursive function def recur(v, ans, adj, vis): # Marking current node visited vis[v] = 1 # Incrementing the counter ans[ 0 ] + = 1 # Traversing for unvisited neighbors for u in adj[v]: if not vis[u]: recur(u, ans, adj, vis) # Unmarking for counting all simple paths vis[v] = 0 # Function to count number of simple paths from given source node 1 def isPossible(N, edg, M): # Initializing adjacency list adj = [[] for i in range (N + 1 )] # Filling adjacency List for i in range (M): adj[edg[i][ 0 ]].append(edg[i][ 1 ]) adj[edg[i][ 1 ]].append(edg[i][ 0 ]) # Visited array for recursion vis = [ 0 ] * (N + 1 ) # Counter initialized to zero ans = [ 0 ] # Calling dfs function recur( 1 , ans, adj, vis) # Returning answer return ans[ 0 ] # Driver Code if __name__ = = '__main__' : # Input 1 N = 4 edg = [[ 1 , 2 ], [ 2 , 3 ]] M = 2 # Function Call print (isPossible(N, edg, M)) |
Javascript
// recursive function function recur(v, adj, vis) { // Marking current node visited vis[v] = true ; // Incrementing the counter let ans = 1; // Traversing for unvisited neighbors for (let i = 0; i < adj[v].length; i++) { const u = adj[v][i]; if (!vis[u]) { ans += recur(u, adj, vis); } } // Unmarking for counting all simple // paths vis[v] = false ; return ans; } // Function to count number of simple // paths from given source node 1 function isPossible(N, edg, M) { // Initializing adjacency list const adj = []; for (let i = 0; i <= N; i++) { adj.push([]); } // Filling adjacency List for (let i = 0; i < M; i++) { const [u, v] = edg[i]; adj[u].push(v); adj[v].push(u); } // Visited array for recursion const vis = new Array(N + 1).fill( false ); // Counter initialized to zero let ans = 0; // Calling dfs function ans = recur(1, adj, vis); // Returning answer return ans; } // Driver Code ( function main() { // Input 1 const N = 4, edg = [[1, 2], [2, 3]]; const M = 2; // Function Call console.log(isPossible(N, edg, M)); })(); |
C#
using System; using System.Collections.Generic; public class Program { // recursive function static void Recur( int v, ref int ans, List<List< int > > adj, List< int > vis) { // Marking current node visited vis[v] = 1; // Incrementing the counter ans++; // Traversing for unvisited neighbors foreach ( int u in adj[v]) { if (vis[u] == 0) { Recur(u, ref ans, adj, vis); } } // Unmarking for counting all simple paths vis[v] = 0; } // Function to count number of simple // paths from given source node 1 static int IsPossible( int N, int [, ] edg, int M) { // Initializing adjacency list List<List< int > > adj = new List<List< int > >(); for ( int i = 0; i <= N; i++) { adj.Add( new List< int >()); } // Filling adjacency List for ( int i = 0; i < M; i++) { adj[edg[i, 0]].Add(edg[i, 1]); adj[edg[i, 1]].Add(edg[i, 0]); } // Visited array for recursion List< int > vis = new List< int >(); for ( int i = 0; i <= N; i++) { vis.Add(0); } // Counter initialized to zero int ans = 0; // Calling dfs function Recur(1, ref ans, adj, vis); // Returning answer return ans; } // Driver Code public static void Main() { // Input 1 int N = 4; int [, ] edg = { { 1, 2 }, { 2, 3 } }; int M = 2; // Function Call Console.WriteLine(IsPossible(N, edg, M)); } } |
3
Time Complexity: O(N!)
Auxiliary Space: O(1)
New Method (Using Depth First Search (DFS))
In this approach we use Depth First Search (DFS) to compute the number of nodes reachable from node 1 in an undirected graph represented by its adjacency list.
Algorithm
Read input N from the user. Initialize a variable sum to 0. Loop i from 1 to N: a. Add i to sum. Output the value of sum as the sum of the first N positive integers.
Implementation of above code
C++
#include <bits/stdc++.h> using namespace std; const int MAXN = 100005; vector< int > adj[MAXN]; bool vis[MAXN]; void dfs( int u) { vis[u] = true ; for ( int v : adj[u]) { if (!vis[v]) { dfs(v); } } } int main() { // Input 1 int N = 4; int M = 2; int edg[][2] = { { 1, 2 }, { 2, 3 } }; // Build adjacency list for ( int i = 0; i < M; i++) { int u = edg[i][0]; int v = edg[i][1]; adj[u].push_back(v); adj[v].push_back(u); } // Compute number of nodes reachable from node 1 dfs(1); int ans = 0; for ( int i = 1; i <= N; i++) { if (vis[i]) { ans++; } } cout << ans << endl; return 0; } |
3
Time complexity O(N), since the loop iterates N times and each iteration takes a constant amount of time
Space complexity O(1), since it uses a constant amount of memory to store the variables N and sum
Please Login to comment...