Skip to content
Related Articles
Get the best out of our app
GFG App
Open App
geeksforgeeks
Browser
Continue

Related Articles

Count of simple paths starting from source node

Improve Article
Save Article
Like Article
Improve Article
Save Article
Like Article

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


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


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


My Personal Notes arrow_drop_up
Last Updated : 25 Apr, 2023
Like Article
Save Article
Similar Reads
Related Tutorials