題目鏈接: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);
}
}