用到的一個東西叫作樹的prufer編碼,百度百科的就挺好,很好懂java
而後就是組合數了,分紅肯定度和自由度兩類進行計算,具體不說了。ide
須要特判無解的狀況,大概就是n爲1的時候,度不爲0。或者n>1的時候度有小於1的或者肯定的度大於n-2。編碼
須要高精度,偷懶直接用JAVA寫了。spa
1 import java.io.*; 2 import java.math.*; 3 import java.util.*; 4 public class Main 5 { 6 public static void main(String[] args){ 7 Scanner cin = new Scanner(new BufferedInputStream(System.in)); 8 int a[] = new int[1005]; 9 int n = cin.nextInt(),s = 0; 10 for(int i = 1;i<=n;++i)a[i] = cin.nextInt(); 11 if(n==1){ 12 if(a[1]==0||a[1]==-1)System.out.println(1); 13 else System.out.println(0); 14 return; 15 } 16 int m = 0; 17 for(int i = 1;i<=n;++i)if(a[i]!=-1){ 18 if(a[i]<1){System.out.println(0);return;} 19 a[i]--;s+=a[i];m++; 20 } 21 if(s>n-2){System.out.println(0);return;} 22 BigInteger f[] = new BigInteger[1005]; 23 f[1] = BigInteger.ONE;f[0] = f[1]; 24 for(int i = 2;i<=n;++i) 25 f[i] = f[i-1].multiply(BigInteger.valueOf(i)); 26 BigInteger ans = f[n-2].divide(f[n-2-s]); 27 BigInteger x = BigInteger.valueOf(n-m); 28 for(int i = 1;i<=n;++i)if(a[i]!=-1) 29 ans = ans.divide(f[a[i]]); ///已經不少次寫成 ans.divide(f[a[i]]);總是忘記賦值 30 for(int i = 1;i<=n-s-2;++i)ans = ans.multiply(x); 31 System.out.println(ans); 32 } 33 }