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++ 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 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. |
# 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))
|
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));
}
} |
// 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));
})(); |
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
#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;
} |
// Java code to implement the approach import java.util.ArrayList;
import java.util.List;
public class Main {
static final int MAXN = 100005 ;
static List<Integer>[] adj = new ArrayList[MAXN];
static boolean [] vis = new boolean [MAXN];
public static void dfs( int u) {
vis[u] = true ;
for ( int v : adj[u]) {
if (!vis[v]) {
dfs(v);
}
}
}
public static void main(String[] args) {
// Input 1
int N = 4 ;
int M = 2 ;
int [][] edg = {{ 1 , 2 }, { 2 , 3 }};
// Initialize adjacency list
for ( int i = 0 ; i <= N; i++) {
adj[i] = new ArrayList<>();
}
// Build adjacency list
for ( int i = 0 ; i < M; i++) {
int u = edg[i][ 0 ];
int v = edg[i][ 1 ];
adj[u].add(v);
adj[v].add(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++;
}
}
System.out.println(ans);
}
} // This code is contributed by Utkarsh Kumar |
# Python code to implement the approach MAXN = 100005
adj = [[] for _ in range (MAXN)]
vis = [ False ] * MAXN
def dfs(u):
vis[u] = True
for v in adj[u]:
if not vis[v]:
dfs(v)
# Input 1 N = 4
M = 2
edg = [[ 1 , 2 ], [ 2 , 3 ]]
# Initialize adjacency list for i in range (N + 1 ):
adj[i] = []
# Build adjacency list for i in range (M):
u = edg[i][ 0 ]
v = edg[i][ 1 ]
adj[u].append(v)
adj[v].append(u)
# Compute number of nodes reachable from node 1 dfs( 1 )
ans = 0
for i in range ( 1 , N + 1 ):
if vis[i]:
ans + = 1
print (ans)
# This code is contributed by shivamgupta310570 |
using System;
using System.Collections.Generic;
class MainClass {
static readonly int MAXN = 100005;
static List< int >[] adj = new List< int >[MAXN];
static bool [] vis = new bool [MAXN];
public static void Dfs( int u) {
vis[u] = true ;
foreach ( int v in adj[u]) {
if (!vis[v]) {
Dfs(v);
}
}
}
public static void Main( string [] args) {
// Input 1
int N = 4;
int M = 2;
int [][] edg = { new int [] { 1, 2 }, new int [] { 2, 3 } };
// Initialize adjacency list
for ( int i = 0; i <= N; i++) {
adj[i] = new List< int >();
}
// Build adjacency list
for ( int i = 0; i < M; i++) {
int u = edg[i][0];
int v = edg[i][1];
adj[u].Add(v);
adj[v].Add(u);
}
// Compute the number of nodes reachable from node 1
Dfs(1);
int ans = 0;
for ( int i = 1; i <= N; i++) {
if (vis[i]) {
ans++;
}
}
Console.WriteLine(ans);
}
} |
const MAXN = 100005; const adj = new Array(MAXN);
const vis = new Array(MAXN);
for (let i = 0; i < MAXN; i++) {
adj[i] = [];
vis[i] = false ;
} function dfs(u) {
vis[u] = true ;
for (const v of adj[u]) {
if (!vis[v]) {
dfs(v);
}
}
} // Input 1 const N = 4; const M = 2; const edg = [[1, 2], [2, 3]]; // Build adjacency list for (let i = 0; i < M; i++) {
const u = edg[i][0];
const v = edg[i][1];
adj[u].push(v);
adj[v].push(u);
} // Compute the number of nodes reachable from node 1 dfs(1); let ans = 0; for (let i = 1; i <= N; i++) {
if (vis[i]) {
ans++;
}
} console.log(ans); // this code is contributed by utkarsh |
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