Number of trees whose sum of degrees of all the vertices is L
Last Updated :
18 Sep, 2023
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++
#include <iostream>
using namespace std;
#define ll long long int
ll power( int x, ll y)
{
ll res = 1;
while (y > 0) {
if (y & 1)
res = (res * x);
y = y >> 1;
x = (x * x);
}
return res;
}
ll solve( int L)
{
int n = L / 2 + 1;
ll ans = power(n, n - 2);
return ans;
}
int main()
{
int L = 6;
cout << solve(L);
return 0;
}
|
Java
import java.io.*;
class GFG
{
static long power( int x, long y)
{
long res = 1 ;
while (y > 0 )
{
if (y== 1 )
res = (res * x);
y = y >> 1 ;
x = (x * x);
}
return res;
}
static long solve( int L)
{
int n = L / 2 + 1 ;
long ans = power(n, n - 2 );
return ans;
}
public static void main (String[] args)
{
int L = 6 ;
System.out.println (solve(L));
}
}
|
Python3
def power(x, y):
res = 1 ;
while (y > 0 ):
if (y % 2 = = 1 ):
res = (res * x);
y = int (y) >> 1 ;
x = (x * x);
return res;
def solve(L):
n = L / 2 + 1 ;
ans = power(n, n - 2 );
return int (ans);
L = 6 ;
print (solve(L));
|
C#
using System;
class GFG
{
static long power( int x, long y)
{
long res = 1;
while (y > 0)
{
if (y == 1)
res = (res * x);
y = y >> 1;
x = (x * x);
}
return res;
}
static long solve( int L)
{
int n = L / 2 + 1;
long ans = power(n, n - 2);
return ans;
}
static public void Main ()
{
int L = 6;
Console.WriteLine(solve(L));
}
}
|
Javascript
<script>
function power(x, y)
{
var res = 1;
while (y > 0) {
if (y & 1)
res = (res * x);
y = y >> 1;
x = (x * x);
}
return res;
}
function solve(L)
{
var n = L / 2 + 1;
var ans = power(n, n - 2);
return ans;
}
var L = 6;
document.write( solve(L));
</script>
|
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:
- 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).
- 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).
- 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.
- 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.
C++
#include <iostream>
using namespace std;
#define ll long long int
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;
}
}
ll countTrees( int n, int L)
{
if (n == 1 && L == 0) {
return 1;
}
if (n > 1 && L == 2 * (n - 1)) {
return power(n, n - 2);
}
ll ans = 0;
for ( int d = 1; d <= min(L - 1, n - 1); d++) {
ll leftCount = countTrees(d, L - d);
ll rightCount = countTrees(n - d, d - 1);
ans += leftCount * rightCount;
}
return ans;
}
int main()
{
int L = 6;
int n = L / 2 + 1;
cout << countTrees(n, L);
return 0;
}
|
Java
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));
}
public 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;
}
}
public static long countTrees( int n, int L) {
if (n == 1 && L == 0 ) {
return 1 ;
}
if (n > 1 && L == 2 * (n - 1 )) {
return power(n, n - 2 );
}
long ans = 0 ;
for ( int d = 1 ; d <= Math.min(L - 1 , n - 1 ); d++) {
long leftCount = countTrees(d, L - d);
long rightCount = countTrees(n - d, d - 1 );
ans += leftCount * rightCount;
}
return ans;
}
}
|
Python3
def power(x, y):
if y = = 0 :
return 1
elif y % 2 = = 0 :
temp = power(x, y / / 2 )
return temp * temp
else :
temp = power(x, y / / 2 )
return x * temp * temp
def count_trees(n, L):
if n = = 1 and L = = 0 :
return 1
if n > 1 and L = = 2 * (n - 1 ):
return power(n, n - 2 )
ans = 0
for d in range ( 1 , min (L - 1 , n - 1 ) + 1 ):
left_count = count_trees(d, L - d)
right_count = count_trees(n - d, d - 1 )
ans + = left_count * right_count
return ans
if __name__ = = "__main__" :
L = 6
n = L / / 2 + 1
result = count_trees(n, L)
print ( result)
|
C#
using System;
public class GFG {
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;
}
}
static long CountTrees( int n, int L)
{
if (n == 1 && L == 0) {
return 1;
}
if (n > 1 && L == 2 * (n - 1)) {
return Power(n, n - 2);
}
long ans = 0;
for ( int d = 1; d <= Math.Min(L - 1, n - 1); d++) {
long leftCount = CountTrees(d, L - d);
long rightCount = CountTrees(n - d, d - 1);
ans += leftCount * rightCount;
}
return ans;
}
public static void Main()
{
int L = 6;
int n = L / 2 + 1;
Console.WriteLine(CountTrees(n, L));
}
}
|
Javascript
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;
}
}
function countTrees(n, L) {
if (n === 1 && L === 0) {
return 1;
}
if (n > 1 && L === 2 * (n - 1)) {
return power(n, n - 2);
}
let ans = 0;
for (let d = 1; d <= Math.min(L - 1, n - 1); d++) {
let leftCount = countTrees(d, L - d);
let rightCount = countTrees(n - d, d - 1);
ans += leftCount * rightCount;
}
return ans;
}
function main() {
let L = 6;
let n = Math.floor(L / 2) + 1;
console.log(countTrees(n, L));
}
main();
|
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)).
Share your thoughts in the comments
Please Login to comment...