uva 10247 complete tree labeling

本文探讨了如何为完全K叉树的节点进行编号的问题,旨在确定满足特定条件的不同编号方式的数量。输入包括树的分支因子和深度,输出则是可能的编号方案数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Problem B

Complete Tree Labeling!

Input: standard input

Output: standard output

Time Limit: 45 seconds

Memory Limit: 32 MB

 

A complete k-ary tree is a k-ary tree in which all leaves have same depth and all internal nodes have degree k. Thisk is also known as the branching factor of a tree. It is very easy to determine the number of nodes of such a tree. Given the depth and branching factor of such a tree, you will have to determine in how many different ways you can number the nodes of the tree so that the label of each node is less that that of its descendants. You should assume that for numbering a tree with N nodes you have the (1, 2, 3, N-1, N) labels available.

 

Input

The input file will contain several lines of input. Each line will contain two integers k and d. Here k is the branching factor of the complete k-ary tree and d is the depth of the complete k-ary tree (k>0, d>0, k*d<=21).

 

Output

For each line of input, produce one line of output containing a round number, which is the number of ways the k-ary tree can be labeled, maintaining the constraints described above.

 

Sample Input:

2 2

10 1

 

Sample Output:

80

3628800


(World Final Warm-up Contest, Problem Setter: Shahriar Manzoor)



import java.math.BigInteger;
import java.util.Scanner;

public class Main {

    static final boolean debug = false;

    public static BigInteger C (int m, int n) {
        if (m - n < n) {
            n = m - n;
        }
        BigInteger c = new BigInteger ("1");
        for (int i=1; i<=n; ++i) {
            c = c.multiply (BigInteger.valueOf (m - i + 1));
            c = c.divide (BigInteger.valueOf (i));
        }
        if (debug) {
            System.out.println ("C (" + m + ", " + n + ") = " + c);
        }
        return c;
    }

    public static int power (int k, int d) {
        int n = 1;
        while (d != 0) {
            if ((d & 1) == 1) {
                n *= k;
            }
            k = k * k;
            d >>= 1;
        }
        return n;
    }

    public static void main (String[] args) {

        int nodes[][] = new int[30][30];
        for (int k=0; k<30; ++k) {
            for (int d=0; d<30 && d*k<=21; ++d) {
                if (k == 0 || d == 0) {
                    nodes[k][d] = 1;
                } else {
                    nodes[k][d] = nodes[k][d - 1] + power (k, d);
                }
                if (debug) {
                    assert nodes[k][d] > 0;
                    System.out.println ("nodes[" + k + "][" + d + "] = " + nodes[k][d]);
                }
            }
        }

        BigInteger f[][] = new BigInteger[30][30];
        for (int k=0; k<30; ++k) {
            for (int d=0; d<30; ++d) {
                f[k][d] = new BigInteger ("1");
            }
        }

        for (int k=1; k<=21; ++k) {
            for (int d=1; k*d<=21; ++d) {
                for (int i=1; i<=k; ++i) {
                    f[k][d] = f[k][d].multiply (C (i * nodes[k][d - 1], nodes[k][d - 1]));
                    f[k][d] = f[k][d].multiply (f[k][d - 1]);
                }
            }
        }

        Scanner scanner = new Scanner (System.in);
        while (scanner.hasNext()) {
            int k = scanner.nextInt();
            int d = scanner.nextInt();
            System.out.println (f[k][d]);
        }
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值