Problem
You are given degree sequence , determine the number of possible caterpillars.
We say that the graphs are different if they are not isomorphic.
Solution
Let us prove first prove the following fact: the degree sequence can form a tree if and only if the sum of degree sequence is equal to and that .
The only if direction is true by the definition of tree. Now for the if direction, let denote the number of leafs, then Chain non-leafs together with edges, which would mean that the number of available edges is which in fact corresponds to the number of leafs, so all of the leafs can be fitted around this chain, forming a caterpillar tree.
Now knowing this, if in the sequence there exists or the sum of the sequence is not equal to the , where is the length of the sequence, then the number of possible caterpillars would be .
So, henceforth, assume that the previous conditions are met. Recall that the caterpillar is a tree in which all the vertices are within distance of the central path. This means that we simply need to find the number of non-isomorphic central paths, since all nodes that are not in the central path are simply leafs. This is actually equivalent to finding number of sequences , where ’s stand for non-one values from sequence , where no two are semordnilapic. This is equal to number of all sequences plus number of palindromes, all divided by , since division by removes duplicate semordnilapics and palindrome addition still keeps palindromes.
So let us denote number of ’s in as , hence . To find the number of all different sequences , then by permutations, the result is
Now, to find the number of palindromic sequences , first of all, if denotes the number of ’s (), which are odd,
- then for all , there are no palindromic sequences, i.e. .
- If and is even, there are no palindromic sequences, again .
- If and is odd, we again have .
- For and odd or and even, by permutations, the result is
Thus, the answer is .
Here is the implementation for Python:
import math
def nr_of_caterpillars(A):
V = len(A)
if sum(A) != 2 * (V - 1):
print("This cannot be a tree.")
return 0
freq = [0] * V
for i in range(V):
freq[A[i]] += 1
if freq[0] > 0:
print("This cannot be a tree.")
return 0
seq = V - freq[1]
odds = len(list(filter(lambda x: x % 2 == 1, freq[2:])))
c = math.factorial(seq)
d = 0
if odds == 1 and seq % 2 == 1 or odds == 0 and seq % 2 == 0:
d = math.factorial(math.floor(seq / 2))
for i in range(2,V):
c = c / math.factorial(freq[i])
d = d / math.factorial(math.floor(freq[i] / 2))
return (int)((c + d) / 2)