Count paths of Tree such that starting and ending node values are same
Given a tree with N nodes, an array A[] of size N denoting the value of each node and array edges [][] of size (N-1), the task is to count the total number of paths such that the starting and the ending node values of the path are equal and no other node in the path has a greater value than the starting node.
Examples:
Input: N = 5, edges[][] = {{1, 2}, {1, 3}, {3, 4}, {3, 5}}, A = {2, 3, 1, 3, 2}
Output: 2
Explanation: There are only 2 paths possible: 1 -> 3 -> 5 and 2 -> 1 -> 3 -> 4.Input: N = 3, edges[][] = {{1, 2}, {2, 3}}, A = {0, 1, 4}
Output: 0
Explanation: There isn’t any path possible.
Approach: This problem can be solved using depth first search:
From each node traverse the tree and check how many nodes have the same value as this one. Add those as a possible path. The final count will be twice the answer as each path will be considered twice in this way.
Follow the steps mentioned below to implement the idea:
- Declare a variable ‘Ans’ and initialize to 0.
- Start a depth-first search from every node in the tree.
- For every node whose value is equal to starting node increment the ‘Ans’ variable to 1.
- If a node is reached whose value is greater than the starting node, then there is no path possible below this node.
- The number of paths calculated is twice the actual count. So divide the answer by 2.
- Return the value of the Ans variable.
Below is the implementation of the above approach.
C++
// C++ code to implement the approach #include <bits/stdc++.h> using namespace std; // Function for dfs void dfs( int src, int StartValue, vector< int > edge[], int A[], int & ans, int parent) { for ( auto it : edge[src]) { if (it != parent) { int CurrentValue = A[it - 1]; if (CurrentValue > StartValue) continue ; if (CurrentValue == StartValue) ans++; dfs(it, StartValue, edge, A, ans, src); } } return ; } // Function for counting total number of path int CountSpecialPath( int N, int edges[][2], int A[]) { // Construct the graph vector< int > edge[N + 1]; for ( int i = 0; i < N - 1; i++) { int x = edges[i][0]; int y = edges[i][1]; edge[x].push_back(y); edge[y].push_back(x); } int ans = 0; for ( int i = 1; i <= N; i++) { int StartValue = A[i - 1]; dfs(i, StartValue, edge, A, ans, -1); } // As each path is considered twice, // divide the answer by 2 ans /= 2; return ans; } // Driver code int main() { int N = 5; int edges[][2] = { { 1, 2 }, { 1, 3 }, { 3, 4 }, { 4, 5 } }; int A[] = { 2, 3, 1, 2, 3 }; // Functions call cout << CountSpecialPath(N, edges, A); return 0; } |
Java
// Java code to implement the approach import java.util.*; class GFG { static int ans; static void dfs( int src, int StartValue, ArrayList<ArrayList<Integer> > edge, int A[], int parent) { for (Integer it : edge.get(src)) { if (it != parent) { int CurrentValue = A[it - 1 ]; if (CurrentValue > StartValue) continue ; if (CurrentValue == StartValue) ans++; dfs(it, StartValue, edge, A, src); } } return ; } // Function for counting total number of path static int CountSpecialPath( int N, int [][] edges, int A[]) { // Construct the graph ArrayList<ArrayList<Integer> > edge = new ArrayList<>(); for ( int i = 0 ; i <= N; i++) { edge.add( new ArrayList<>()); } for ( int i = 0 ; i < N - 1 ; i++) { int x = edges[i][ 0 ]; int y = edges[i][ 1 ]; edge.get(x).add(y); edge.get(y).add(x); } ans = 0 ; for ( int i = 1 ; i <= N; i++) { int StartValue = A[i - 1 ]; dfs(i, StartValue, edge, A, - 1 ); } // As each path is considered twice, // divide the answer by 2 ans /= 2 ; return ans; } // Driver code public static void main(String[] args) { int N = 5 ; int [][] edges = { { 1 , 2 }, { 1 , 3 }, { 3 , 4 }, { 4 , 5 } }; int A[] = { 2 , 3 , 1 , 2 , 3 }; // Functions call System.out.println(CountSpecialPath(N, edges, A)); } } // This code is contributed by karandeep1234. |
Python3
# Python3 code to implement the approach ans = 0 # Function for dfs def dfs(src, StartValue, edge, A, parent): global ans for it in edge[src]: if (it ! = parent): CurrentValue = A[it - 1 ] if (CurrentValue > StartValue): continue if (CurrentValue = = StartValue): ans + = 1 dfs(it, StartValue, edge, A, src) return # Function for counting total number of path def CountSpecialPath(N, edges, A): global ans # Construct the graph edge = [[] for _ in range (N + 1 )] for i in range ( 0 , N - 1 ): x = edges[i][ 0 ] y = edges[i][ 1 ] edge[x].append(y) edge[y].append(x) ans = 0 for i in range ( 1 , N + 1 ): StartValue = A[i - 1 ] dfs(i, StartValue, edge, A, - 1 ) # As each path is considered twice, # divide the answer by 2 ans / / = 2 return ans # Driver code if __name__ = = "__main__" : N = 5 edges = [[ 1 , 2 ], [ 1 , 3 ], [ 3 , 4 ], [ 4 , 5 ]] A = [ 2 , 3 , 1 , 2 , 3 ] # Functions call print (CountSpecialPath(N, edges, A)) # This code is contributed by rakeshsahni |
C#
// C# code to implement the approach using System; using System.Collections.Generic; class GFG { static int ans; static void dfs( int src, int StartValue, List<List< int > > edge, int [] A, int parent) { foreach ( int it in edge[src]) { if (it != parent) { int CurrentValue = A[it - 1]; if (CurrentValue > StartValue) continue ; if (CurrentValue == StartValue) ans++; dfs(it, StartValue, edge, A, src); } } return ; } // Function for counting total number of path static int CountSpecialPath( int N, int [,] edges, int [] A) { // Construct the graph List<List< int > > edge = new List<List< int >>(); for ( int i = 0; i <= N; i++) { edge.Add( new List< int >()); } for ( int i = 0; i < N - 1; i++) { int x = edges[i,0]; int y = edges[i,1]; edge[x].Add(y); edge[y].Add(x); } ans = 0; for ( int i = 1; i <= N; i++) { int StartValue = A[i - 1]; dfs(i, StartValue, edge, A, -1); } // As each path is considered twice, // divide the answer by 2 ans /= 2; return ans; } // Driver code public static void Main() { int N = 5; int [,] edges = { { 1, 2 }, { 1, 3 }, { 3, 4 }, { 4, 5 } }; int [] A = { 2, 3, 1, 2, 3 }; // Functions call Console.Write(CountSpecialPath(N, edges, A)); } } // This code is contributed by Saurabh Jaiswal |
Javascript
// JavaScript code for the above approach // Function for dfs let ans = 0; function dfs(src, StartValue, edge, A, parent) { edge[src].forEach((it) => { if (it !== parent) { let CurrentValue = A[it - 1]; if (CurrentValue > StartValue) return ; if (CurrentValue === StartValue) ans++; dfs(it, StartValue, edge, A, src); } }); return ; } // Function for counting total number of path function CountSpecialPath(N, edges, A) { // construct the graph let edge = []; for (let i = 0; i <= N; i++) { edge.push([]); } for (let i = 0; i < N - 1; i++) { let x = edges[i][0]; let y = edges[i][1]; edge[x].push(y); edge[y].push(x); } for (let i = 1; i <= N; i++) { let StartValue = A[i - 1]; dfs(i, StartValue, edge, A, -1); } // As each path is considered twice, // divide the answer by 2 ans = Math.floor(ans / 2); return ans; } // Test case let N = 5; let edges = [[1, 2], [1, 3], [3, 4], [4, 5]]; let A = [2, 3, 1, 2, 3]; // Functions call console.log(CountSpecialPath(N, edges, A)); // This code is contributed by Potta Lokesh |
2
Time complexity: O(N2)
- As for every node we are traversing the whole tree in a depth-first search so the time taken to traverse a tree would be O(N).
- As there is N number of total nodes present in the tree, So the overall time complexity would be O(N2).
Auxiliary Space: O(N)
Please Login to comment...