题意

N个点,有些点有度数限制,问这些点可以构成几棵不同的树。

思路


【Prufer数列】

Prufer数列是无根树的一种数列。在组合数学中,Prufer数列是由一个对于顶点标过号的树转化来的数列,点数为n的树转化来的Prufer数列长度为n-2。一个Prufer数列唯一对应一棵树。

【将树转化成Prufer数列的方法】

一种生成Prufer序列的方法是迭代删点,直到原图仅剩两个点。对于一棵顶点已经经过编号的树T,顶点的编号为{1,2,...,n},在第i步时,移去所有叶子节点(度为1的顶点)中标号最小的顶点和相连的边,并把与它相邻的点的编号加入Prufer序列中,重复以上步骤直到原图仅剩2个顶点。


显然本题就是求不同的Prufer数列个数,由于有些点有度数限制,假设这些点度数分别为d[i],则该点在数列中就需要出现d[i]-1次。

令sum = sigma(d[i]-1),则sum表示所有w个有度数限制的点在数列中占几位。

先为这些点分配位置:P1 = C(n-2, sum)*sum!/∏(d[i]-1)!

然后剩下n-w个点,n-sum-2个空位,P = P1 * (n-w)n-sum-2.

代码

[cpp]
/**************************************************************
Problem: 1005
User: AbandonZHANG
Language: Java
Result: Accepted
Time:1284 ms
Memory:19092 kb
****************************************************************/

import java.util.*;
import java.math.*;

public class Main{
public static void main(String args[]){
Scanner cin = new Scanner(System.in);
int a[] = new int[1005];
int n, w = 0, sum = 0;
n = cin.nextInt();
BigInteger ww = BigInteger.ONE, ws;
for (int i = 0; i < n; i ++){
a[i] = cin.nextInt();
if (a[i] > -1){
w ++;
sum += (a[i] - 1);
ww = ww.multiply(fac(a[i]-1));
}
}
ws = fac(sum);
BigInteger res = BigInteger.ONE, wp = BigInteger.valueOf(n-w);
res = res.multiply(C(n-2, sum));
res = res.multiply(ws.divide(ww));
res = res.multiply(wp.pow(n-sum-2));
System.out.println(res);
cin.close();
}
public static BigInteger fac(int n){
BigInteger res;
res = BigInteger.ONE;
while(n != 0){
res = res.multiply(BigInteger.valueOf(n));
n --;
}
return res;
}
public static BigInteger C(int n, int r){
BigInteger res = BigInteger.ONE;
res = res.multiply(fac(n));
res = res.divide(fac(r).multiply(fac(n-r)));
return res;
}
}
[/cpp]

BZOJ 1005 [HNOI2008]明明的烦恼 ★(Prufer数列)的更多相关文章

  1. bzoj 1005: [HNOI2008]明明的烦恼 prufer编号&&生成树计数

    1005: [HNOI2008]明明的烦恼 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2248  Solved: 898[Submit][Statu ...

  2. BZOJ 1005 [HNOI2008]明明的烦恼 (Prufer编码 + 组合数学 + 高精度)

    1005: [HNOI2008]明明的烦恼 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 5786  Solved: 2263[Submit][Stat ...

  3. bzoj 1005 [HNOI2008] 明明的烦恼 (prufer编码)

    [HNOI2008]明明的烦恼 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 5907  Solved: 2305[Submit][Status][Di ...

  4. BZOJ.1005.[HNOI2008]明明的烦恼(Prufer 高精 排列组合)

    题目链接 若点数确定那么ans = (n-2)!/[(d1-1)!(d2-1)!...(dn-1)!] 现在把那些不确定的点一起考虑(假设有m个),它们在Prufer序列中总出现数就是left=n-2 ...

  5. BZOJ 1005 [HNOI2008] 明明的烦恼(组合数学 Purfer Sequence)

    题目大意 自从明明学了树的结构,就对奇怪的树产生了兴趣...... 给出标号为 1 到 N 的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少棵度数满足要求的树? Input 第一行为 N( ...

  6. BZOJ 1005: [HNOI2008]明明的烦恼( 组合数学 + 高精度 )

    首先要知道一种prufer数列的东西...一个prufer数列和一颗树对应..然后树上一个点的度数-1是这个点在prufer数列中出现次数..这样就转成一个排列组合的问题了.算个可重集的排列数和组合数 ...

  7. BZOJ 1005: [HNOI2008]明明的烦恼 Purfer序列 大数

    1005: [HNOI2008]明明的烦恼 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/ ...

  8. BZOJ 1005 [HNOI2008]明明的烦恼 purfer序列,排列组合

    1005: [HNOI2008]明明的烦恼 Description 自从明明学了树的结构,就对奇怪的树产生了兴趣......给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少 ...

  9. BZOJ 1005: [HNOI2008]明明的烦恼(prufer数列)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1005 题意: Description 自从明明学了树的结构,就对奇怪的树产生了兴趣......给出标 ...

随机推荐

  1. 浅析selenium的PageFactory模式 PageFactory初始化pageobject

    1.首先介绍FindBy类: For example, these two annotations point to the same element: @FindBy(id = "foob ...

  2. python全栈开发从入门到放弃之迭代器生成器

    1.python中的for循环 l = [1,2,3,4,5,6] for i in l: #根据索引取值 print(i) 输出结果: 1 2 3 4 5 6 2.iterable  可迭代的 可迭 ...

  3. python全栈开发从入门到放弃之面向对象反射

    1.classmethod.staticmethod方法 classmethod类方法默认参数cls,可以直接用类名调用,可以与类属性交互 #student文件内容 宝宝,男 博博,女 海娇,男 海燕 ...

  4. 130. Surrounded Regions(周围区域问题 广度优先)(代码未完成!!)

    Given a 2D board containing 'X' and 'O' (the letter O), capture all regions surrounded by 'X'. A reg ...

  5. android 如何获取当前的Activity类名

    比如友盟统计页面停留时间,咱们需要知道当前页面停留了多久. 一般我们都有一个父类Activity,用下面的方法可以获得完整的包名.类名结构 this.getLocalClassName() 输出如下: ...

  6. laravel 环境配置

    一.composer 安装 1.确定为最新版本的PHP 2.进入Composer官网下载页面,在页面最下方Manual Download区域选择需要的版本下载. 3.将下载的composer.phar ...

  7. 异常信息 Exception

    void GetExceptionMsg(Exception ex, StringBuilder sb, string Prefix = "") { sb.AppendLine(P ...

  8. PHP 实现归并排序算法

    算法原理 原理: 利用递归,先拆分.后合并.再排序. 步骤: 均分数列为两个子数列 递归重复上一步骤,直到子数列只有一个元素 父数列合并两个子数列并排序,递归返回数列 代码实现 // 归并排序主程序 ...

  9. 照着官网来安装openstack pike之创建并启动instance

    有了之前组件(keystone.glance.nova.neutron)的安装后,那么就可以在命令行创建并启动instance了 照着官网来安装openstack pike之environment设置 ...

  10. sudo fdisk -l

      施其振 2015/1/31 22:06:26 第一行十大5 施其振 2015/1/31 22:06:39 第一行sda5 施其振 2015/1/31 22:06:49 是你的固态硬盘 施其振 20 ...