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++
#include <bits/stdc++.h>
using namespace std;
void recur( int v, int & ans, vector<vector< int > >& adj,
vector< int >& vis)
{
vis[v] = 1;
ans++;
for ( auto & u : adj[v]) {
if (!vis[u]) {
recur(u, ans, adj, vis);
}
}
vis[v] = 0;
}
int isPossible( int N, int edg[][2], int M)
{
vector<vector< int > > adj(N + 1);
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]);
}
vector< int > vis(N + 1, 0);
int ans = 0;
recur(1, ans, adj, vis);
return ans;
}
int main()
{
int N = 4, edg[][2] = { { 1, 2 }, { 2, 3 } };
int M = 2;
cout << isPossible(N, edg, M) << endl;
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
static void recur( int v, int [] ans,
ArrayList<ArrayList<Integer> > adj,
int [] vis)
{
vis[v] = 1 ;
ans[ 0 ]++;
for ( int u : adj.get(v)) {
if (vis[u] == 0 ) {
recur(u, ans, adj, vis);
}
}
vis[v] = 0 ;
}
static int isPossible( int N, int [][] edg, int M)
{
ArrayList<ArrayList<Integer> > adj
= new ArrayList<>();
for ( int i = 0 ; i <= N; i++) {
adj.add( new ArrayList<Integer>());
}
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 ]);
}
int [] vis = new int [N + 1 ];
int [] ans = { 0 };
recur( 1 , ans, adj, vis);
return ans[ 0 ];
}
public static void main(String[] args)
{
int N = 4 ;
int [][] edg = { { 1 , 2 }, { 2 , 3 } };
int M = 2 ;
System.out.println(isPossible(N, edg, M));
}
}
|
Python3
def recur(v, ans, adj, vis):
vis[v] = 1
ans[ 0 ] + = 1
for u in adj[v]:
if not vis[u]:
recur(u, ans, adj, vis)
vis[v] = 0
def isPossible(N, edg, M):
adj = [[] for i in range (N + 1 )]
for i in range (M):
adj[edg[i][ 0 ]].append(edg[i][ 1 ])
adj[edg[i][ 1 ]].append(edg[i][ 0 ])
vis = [ 0 ] * (N + 1 )
ans = [ 0 ]
recur( 1 , ans, adj, vis)
return ans[ 0 ]
if __name__ = = '__main__' :
N = 4
edg = [[ 1 , 2 ], [ 2 , 3 ]]
M = 2
print (isPossible(N, edg, M))
|
C#
using System;
using System.Collections.Generic;
public class Program {
static void Recur( int v, ref int ans,
List<List< int > > adj, List< int > vis)
{
vis[v] = 1;
ans++;
foreach ( int u in adj[v])
{
if (vis[u] == 0) {
Recur(u, ref ans, adj, vis);
}
}
vis[v] = 0;
}
static int IsPossible( int N, int [, ] edg, int M)
{
List<List< int > > adj = new List<List< int > >();
for ( int i = 0; i <= N; i++) {
adj.Add( new List< int >());
}
for ( int i = 0; i < M; i++) {
adj[edg[i, 0]].Add(edg[i, 1]);
adj[edg[i, 1]].Add(edg[i, 0]);
}
List< int > vis = new List< int >();
for ( int i = 0; i <= N; i++) {
vis.Add(0);
}
int ans = 0;
Recur(1, ref ans, adj, vis);
return ans;
}
public static void Main()
{
int N = 4;
int [, ] edg = { { 1, 2 }, { 2, 3 } };
int M = 2;
Console.WriteLine(IsPossible(N, edg, M));
}
}
|
Javascript
function recur(v, adj, vis) {
vis[v] = true ;
let ans = 1;
for (let i = 0; i < adj[v].length; i++) {
const u = adj[v][i];
if (!vis[u]) {
ans += recur(u, adj, vis);
}
}
vis[v] = false ;
return ans;
}
function isPossible(N, edg, M) {
const adj = [];
for (let i = 0; i <= N; i++) {
adj.push([]);
}
for (let i = 0; i < M; i++) {
const [u, v] = edg[i];
adj[u].push(v);
adj[v].push(u);
}
const vis = new Array(N + 1).fill( false );
let ans = 0;
ans = recur(1, adj, vis);
return ans;
}
( function main() {
const N = 4, edg = [[1, 2], [2, 3]];
const M = 2;
console.log(isPossible(N, edg, M));
})();
|
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() {
int N = 4;
int M = 2;
int edg[][2] = { { 1, 2 }, { 2, 3 } };
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);
}
dfs(1);
int ans = 0;
for ( int i = 1; i <= N; i++) {
if (vis[i]) {
ans++;
}
}
cout << ans << endl;
return 0;
}
|
Java
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) {
int N = 4 ;
int M = 2 ;
int [][] edg = {{ 1 , 2 }, { 2 , 3 }};
for ( int i = 0 ; i <= N; i++) {
adj[i] = new ArrayList<>();
}
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);
}
dfs( 1 );
int ans = 0 ;
for ( int i = 1 ; i <= N; i++) {
if (vis[i]) {
ans++;
}
}
System.out.println(ans);
}
}
|
Python3
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)
N = 4
M = 2
edg = [[ 1 , 2 ], [ 2 , 3 ]]
for i in range (N + 1 ):
adj[i] = []
for i in range (M):
u = edg[i][ 0 ]
v = edg[i][ 1 ]
adj[u].append(v)
adj[v].append(u)
dfs( 1 )
ans = 0
for i in range ( 1 , N + 1 ):
if vis[i]:
ans + = 1
print (ans)
|
C#
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) {
int N = 4;
int M = 2;
int [][] edg = { new int [] { 1, 2 }, new int [] { 2, 3 } };
for ( int i = 0; i <= N; i++) {
adj[i] = new List< int >();
}
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);
}
Dfs(1);
int ans = 0;
for ( int i = 1; i <= N; i++) {
if (vis[i]) {
ans++;
}
}
Console.WriteLine(ans);
}
}
|
Javascript
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);
}
}
}
const N = 4;
const M = 2;
const edg = [[1, 2], [2, 3]];
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);
}
dfs(1);
let ans = 0;
for (let i = 1; i <= N; i++) {
if (vis[i]) {
ans++;
}
}
console.log(ans);
|
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
Last Updated :
09 Nov, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...