Open In App

Number of trees whose sum of degrees of all the vertices is L

Given an integer L which is the sum of degrees of all the vertices of some tree. The task is to find the count of all such distinct trees (labeled trees). Two trees are distinct if they have at least a single different edge.
Examples: 
 

Input: L = 2 
Output: 1
Input: L = 6 
Output: 16 
 



 

Simple Solution: A simple solution is to find the number of nodes of the tree which has sum of degrees of all vertices as L. Number of nodes in such a tree is n = (L / 2 + 1) as described in this article. 
Now the solution is to form all the labeled trees which can be formed using n nodes. This approach is quite complex and for larger values of n it is not possible to find out the number of trees using this process.
Efficient Solution: An efficient solution is to find the number of nodes using Cayley’s formula which states that there are n(n – 2) trees with n labeled vertices. So the time complexity of the code now reduces to O(n) which can be further reduced to O(logn) using modular exponentiation.
Below is the implementation of the above approach:
 






// C++ implementation of the approach
#include <iostream>
using namespace std;
#define ll long long int
 
// Iterative Function to calculate (x^y) in O(log y)
ll power(int x, ll y)
{
 
    // Initialize result
    ll res = 1;
 
    while (y > 0) {
 
        // If y is odd, multiply x with result
        if (y & 1)
            res = (res * x);
 
        // y must be even now
        // y = y / 2
        y = y >> 1;
        x = (x * x);
    }
    return res;
}
 
// Function to return the count
// of required trees
ll solve(int L)
{
    // number of nodes
    int n = L / 2 + 1;
 
    ll ans = power(n, n - 2);
 
    // Return the result
    return ans;
}
 
// Driver code
int main()
{
    int L = 6;
 
    cout << solve(L);
 
    return 0;
}




// Java implementation of the approach
import java.io.*;
 
class GFG
{
     
// Iterative Function to calculate (x^y) in O(log y)
static long power(int x, long y)
{
 
    // Initialize result
    long res = 1;
 
    while (y > 0)
    {
 
        // If y is odd, multiply x with result
        if (y==1)
            res = (res * x);
 
        // y must be even now
        // y = y / 2
        y = y >> 1;
        x = (x * x);
    }
    return res;
}
 
// Function to return the count
// of required trees
static long solve(int L)
{
    // number of nodes
    int n = L / 2 + 1;
 
    long ans = power(n, n - 2);
 
    // Return the result
    return ans;
}
 
// Driver code
public static void main (String[] args)
{
 
    int L = 6;
    System.out.println (solve(L));
}
}
 
// This code is contributed by ajit.




     
# Python implementation of the approach
 
# Iterative Function to calculate (x^y) in O(log y)
def power(x, y):
 
    # Initialize result
    res = 1;
 
    while (y > 0):
 
        # If y is odd, multiply x with result
        if (y %2== 1):
            res = (res * x);
 
        # y must be even now
        #y = y / 2
        y = int(y) >> 1;
        x = (x * x);
    return res;
 
 
# Function to return the count
# of required trees
def solve(L):
     
    # number of nodes
    n = L / 2 + 1;
 
    ans = power(n, n - 2);
 
    # Return the result
    return int(ans);
 
L = 6;
print(solve(L));
 
# This code has been contributed by 29AjayKumar




// C# implementation of the approach
using System;
 
class GFG
{
     
// Iterative Function to calculate (x^y) in O(log y)
static long power(int x, long y)
{
 
    // Initialize result
    long res = 1;
 
    while (y > 0)
    {
 
        // If y is odd, multiply x with result
        if (y == 1)
            res = (res * x);
 
        // y must be even now
        // y = y / 2
        y = y >> 1;
        x = (x * x);
    }
    return res;
}
 
// Function to return the count
// of required trees
static long solve(int L)
{
    // number of nodes
    int n = L / 2 + 1;
 
    long ans = power(n, n - 2);
 
    // Return the result
    return ans;
}
 
// Driver code
static public void Main ()
{
    int L = 6;
    Console.WriteLine(solve(L));
}
}
 
// This code is contributed by Tushil.




<script>
 
// Javascript implementation of the approach
 
// Iterative Function to calculate (x^y) in O(log y)
function power(x, y)
{
 
    // Initialize result
    var res = 1;
 
    while (y > 0) {
 
        // If y is odd, multiply x with result
        if (y & 1)
            res = (res * x);
 
        // y must be even now
        // y = y / 2
        y = y >> 1;
        x = (x * x);
    }
    return res;
}
 
// Function to return the count
// of required trees
function solve(L)
{
    // number of nodes
    var n = L / 2 + 1;
 
    var ans = power(n, n - 2);
 
    // Return the result
    return ans;
}
 
// Driver code
var L = 6;
document.write( solve(L));
 
// This code is contributed by rutvik_56.
</script>

Output
16






Time Complexity : O(logn)

Auxiliary Space: O(1)

Approach(Using  recursion): Another approach to count trees with a given sum of degrees is to use recursion.

Algorithm:

  1. Define a recursive function that takes two arguments: n (the number of vertices in the tree) and L (the sum of degrees of all vertices).
  2. Add the two base cases:
    a. If n is 1 and L is 0 then return 1 (since a tree with one vertex has degree 0).
    b. If n is greater than 1 and L is equal to 2(n-1) then return n^(n-2) (since this is the number of labeled trees with n vertices and sum of degrees L).
  3. For all other values of n and L, iterate over all possible degrees d in the range [1, L-1] (since the degree of a vertex in a tree must be at least 1 and at most L-1) and for each value of d, recursively compute the number of trees with d  vertices and the sum of degrees L-d on the left subtree is  the number of trees with n-d vertices and sum of degrees d-1 on the right subtree.
  4. Multiply the number of trees on the left subtree by the number of trees on the right subtree, and add the result to the running total and return the running total as the answer.

Below is the implementation of above approach.




#include <iostream>
using namespace std;
#define ll long long int
 
// Recursive Function to calculate (x^y) in O(log y)
ll power(int x, ll y)
{
    if (y == 0) {
        return 1;
    } else if (y % 2 == 0) {
        ll temp = power(x, y / 2);
        return temp * temp;
    } else {
        ll temp = power(x, y / 2);
        return x * temp * temp;
    }
}
 
// Recursive function to return the count of required trees
ll countTrees(int n, int L)
{
    // Base case: a tree with one vertex has degree 0
    if (n == 1 && L == 0) {
        return 1;
    }
 
    // Base case: a tree with n vertices has sum of degrees 2(n-1)
    if (n > 1 && L == 2 * (n - 1)) {
        return power(n, n - 2);
    }
 
    ll ans = 0;
 
    // Consider the last vertex in the tree, with degree d in the range [1, L-1]
    for (int d = 1; d <= min(L - 1, n - 1); d++) {
        // Recursively compute the number of trees for each possible value of d
        ll leftCount = countTrees(d, L - d);
        ll rightCount = countTrees(n - d, d - 1);
        ans += leftCount * rightCount;
    }
 
    return ans;
}
 
// Driver code
int main()
{
    int L = 6;
    int n = L / 2 + 1;
 
    cout << countTrees(n, L);
 
    return 0;
}




import java.util.*;
 
public class Main {
    public static void main(String[] args) {
        int L = 6;
        int n = L / 2 + 1;
        System.out.println(countTrees(n, L));
    }
 
    // Recursive function to calculate the power of a number
    public static long power(int x, long y) {
        if (y == 0) {
            return 1;
        } else if (y % 2 == 0) {
            // If y is even, use recursion to calculate x^(y/2) and square it
            long temp = power(x, y / 2);
            return temp * temp;
        } else {
            // If y is odd, use recursion to calculate x^(y/2) and multiply it with x and square it
            long temp = power(x, y / 2);
            return x * temp * temp;
        }
    }
 
    // Recursive function to count the number of unique binary trees that can be formed with n nodes and L levels
    public static long countTrees(int n, int L) {
        // Base case: if we have a single node and no levels (empty tree), there is one possible tree
        if (n == 1 && L == 0) {
            return 1;
        }
 
        // If the tree consists of n nodes and each node has exactly two children, and it has L levels, there's a unique solution.
        if (n > 1 && L == 2 * (n - 1)) {
            // In this case, the number of unique trees can be calculated as n^(n-2)
            return power(n, n - 2);
        }
 
        long ans = 0;
 
        // Try all possible left subtree sizes (d) from 1 to the minimum of (L-1) and (n-1)
        for (int d = 1; d <= Math.min(L - 1, n - 1); d++) {
            // Count the number of unique left subtrees with 'd' nodes and remaining 'L-d' levels
            long leftCount = countTrees(d, L - d);
 
            // Count the number of unique right subtrees with 'n-d' nodes and 'd-1' levels
            long rightCount = countTrees(n - d, d - 1);
 
            // For each combination of left and right subtrees, add their counts to the total count 'ans'
            ans += leftCount * rightCount;
        }
 
        return ans;
    }
}




# Function to calculate the power of a number (x^y) in O(log y)
def power(x, y):
    if y == 0:
        return 1
    elif y % 2 == 0:
        # If y is even, calculate power(x, y // 2) and square it
        temp = power(x, y // 2)
        return temp * temp
    else:
        # If y is odd, calculate power(x, y // 2) and multiply
        # it with x and square it
        temp = power(x, y // 2)
        return x * temp * temp
 
 
# Recursive function to count the number of trees with n
# vertices and a given sum of degrees L
def count_trees(n, L):
    # Base case: a tree with one vertex has degree 0
    if n == 1 and L == 0:
        return 1
 
    # Base case: a tree with n vertices has sum of degrees 2(n-1)
    if n > 1 and L == 2 * (n - 1):
        return power(n, n - 2)
 
    ans = 0
 
    # Consider the last vertex in the tree, with degree d in
    # the range [1, L-1]
    for d in range(1, min(L - 1, n - 1) + 1):
        # Recursively compute the number of trees for each possible
        # value of d
        left_count = count_trees(d, L - d)
        right_count = count_trees(n - d, d - 1)
        ans += left_count * right_count
 
    return ans
 
 
# Driver code
if __name__ == "__main__":
    L = 6
    n = L // 2 + 1
    result = count_trees(n, L)
    print( result)




using System;
 
public class GFG {
    // Recursive Function to calculate (x^y) in O(log y)
    static long Power(int x, long y)
    {
        if (y == 0) {
            return 1;
        }
        else if (y % 2 == 0) {
            long temp = Power(x, y / 2);
            return temp * temp;
        }
        else {
            long temp = Power(x, y / 2);
            return x * temp * temp;
        }
    }
 
    // Recursive function to return the count of required
    // trees
    static long CountTrees(int n, int L)
    {
        // Base case: a tree with one vertex has degree 0
        if (n == 1 && L == 0) {
            return 1;
        }
 
        // Base case: a tree with n vertices has sum of
        // degrees 2(n-1)
        if (n > 1 && L == 2 * (n - 1)) {
            return Power(n, n - 2);
        }
 
        long ans = 0;
 
        // Consider the last vertex in the tree, with degree
        // d in the range [1, L-1]
        for (int d = 1; d <= Math.Min(L - 1, n - 1); d++) {
            // Recursively compute the number of trees for
            // each possible value of d
            long leftCount = CountTrees(d, L - d);
            long rightCount = CountTrees(n - d, d - 1);
            ans += leftCount * rightCount;
        }
 
        return ans;
    }
 
    // Driver code
    public static void Main()
    {
        int L = 6;
        int n = L / 2 + 1;
 
        Console.WriteLine(CountTrees(n, L));
    }
}




// Recursive Function to calculate (x^y) in O(log y)
function power(x, y) {
    if (y === 0) {
        return 1;
    } else if (y % 2 === 0) {
        let temp = power(x, y / 2);
        return temp * temp;
    } else {
        let temp = power(x, Math.floor(y / 2));
        return x * temp * temp;
    }
}
 
// Recursive function to return the count of required trees
function countTrees(n, L) {
    // Base case: a tree with one vertex has degree 0
    if (n === 1 && L === 0) {
        return 1;
    }
 
    // Base case: a tree with n vertices has sum of degrees 2(n-1)
    if (n > 1 && L === 2 * (n - 1)) {
        return power(n, n - 2);
    }
 
    let ans = 0;
 
    // Consider the last vertex in the tree, with degree d in the range [1, L-1]
    for (let d = 1; d <= Math.min(L - 1, n - 1); d++) {
        // Recursively compute the number of trees for each possible value of d
        let leftCount = countTrees(d, L - d);
        let rightCount = countTrees(n - d, d - 1);
        ans += leftCount * rightCount;
    }
 
    return ans;
}
 
// Driver code
function main() {
    let L = 6;
    let n = Math.floor(L / 2) + 1;
 
    console.log(countTrees(n, L));
}
 
main();

Output
16






Time Complexity : O(n^(n-2)), since the number of distinct trees with n vertices is at most n^(n-2) (which is achieved when all vertices have degree 1).

Auxiliary Space: O(n), since each recursive call creates a new activation record on the stack, and the maximum depth of the recursion tree is n (which occurs when the sum of degrees is L = 2(n-1)).


Article Tags :