Open In App

Count paths of Tree such that starting and ending node values are same

Improve
Improve
Like Article
Like
Save
Share
Report

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


Output

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)



Last Updated : 26 Dec, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads