题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1005
题目大意:给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少棵度数满足要求的树。
题目分析:http://www.cnblogs.com/zhj5chengfeng/p/3278557.html
代码参考:
import java.util.*;
import java.io.BufferedInputStream;
import java.math.*;
import java.lang.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(new BufferedInputStream(System.in));
BigInteger f[] = new BigInteger [2000];
int d[] = new int [20000];
int i, n, cnt, sum;
f[0] = BigInteger.ONE;//计算阶乘
for(i=1; i<=1000; ++i) f[i] = f[i-1].multiply(BigInteger.valueOf(i));
n = in.nextInt();
cnt = sum = 0;
boolean flag = false;
for(i=0; i<n; ++i) {
d[i] = in.nextInt();
if(d[i] == 0 || d[i] > n-1) flag = true;//特殊情况判断
if(d[i] == -1) continue;//只计算度数有限定的点
sum += d[i] - 1;
cnt++;//度数有限定的点的个数
}
//特殊情况的处理
if(flag == true) {
System.out.println("0");
return;
}
if(n == 1) {
if(d[0] == -1 || d[0] == 0) System.out.println("1");
else System.out.println("0");
return;
}
if(n == 2) {
if((d[0] == -1 || d[0] == 0) && (d[1] == -1 || d[1] == -1))
System.out.println("1");
else System.out.println("0");
return;
}
//根据公式计算
BigInteger ans = f[n-2];
ans = ans.divide(f[n-2-sum]);
for(i=0; i<n; ++i) {
if(d[i] == -1) continue;
ans = ans.divide(f[d[i]-1]);
}
BigInteger tmp = BigInteger.valueOf(n-cnt).pow(n-2-sum);
ans = ans.multiply(tmp);
System.out.println(ans);
}
}