Open In App

Count of simple paths starting from source node

Improve
Improve
Like Article
Like
Save
Share
Report

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))


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));
    }
}


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));
})();


Output

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;
}


Java




// 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


Python3




# 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


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) {
        // 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);
    }
}


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);
    }
  }
}
 
// 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


Output

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



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