题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1211
洛谷:https://www.luogu.com.cn/problem/P2290
Time Limit: 10 Sec Memory Limit: 162 MBDescription
一个有n个结点的树,设它的结点分别为v1, v2, …, vn,已知第i个结点vi的度数为di,问满足这样的条件的不同的树有多少棵。给定n,d1, d2, …, dn,编程需要输出满足d(vi)=di的树的个数。
Input
第一行是一个正整数n,表示树有n个结点。第二行有n个数,第i个数表示di,即树的第i个结点的度数。其中1<=n<=150,输入数据保证满足条件的树不超过10^17个。
Output
输出满足条件的树有多少棵。
Sample Input
4
2 1 2 1
2 1 2 1
Sample Output
2
裸的Purfer序列,直接套公式:
$frac{(n-2)!}{prod_{i=1}^{n}(d_{i}-1)!}$
然后判断一下有无解的情况,特判n=1的情况
以下是AC代码(python):
n=int(input()) s=0 if n==1: x=int(input()) if x==0: print(1) else : print(0) exit() a=input().split() for i in range(0,n): a[i]=int(a[i]) if a[i]==0: print(0) exit() s+=a[i]-1 f=[1] for i in range(1,n-1): f.append(f[i-1]*i); ss=1 for i in range(0,n): ss*=f[a[i]-1] ans=f[n-2]//ss if s==n-2:print(ans) else :print(0)
然后用Java写一发(毕竟比赛的时候一般没有Python):
import java.math.BigInteger; import java.util.Scanner; class Main{ public static void main(String[] args){ BigInteger f[]=new BigInteger[200]; Scanner sc=new Scanner(System.in); int n=sc.nextInt(); int s=0; int a[]=new int[200]; int mark=0; for (int i=1; i<=n; i++) { a[i] = sc.nextInt(); if (a[i]==0) mark=1; s += a[i] - 1; } if (n==1){ if (a[1]==0) System.out.println("1"); else System.out.println("0"); } else if (mark==1) System.out.println("0"); else{ if (s!=n-2){ System.out.println("0"); System.exit(0); } f[0]=new BigInteger("1"); BigInteger num[]=new BigInteger[200]; num[0]=new BigInteger("0"); for (int i=1; i<=n; i++) num[i]=num[i-1].add(new BigInteger("1")); for (int i=1; i<=n-2; i++) f[i]=f[i-1].multiply(num[i]); BigInteger tot=new BigInteger("1"); BigInteger sum=new BigInteger("1"); for (int i=1; i<=n; i++) tot=tot.multiply(f[a[i]-1]); for (int i=1; i<=s; i++) sum=sum.multiply(num[i]); System.out.println(sum.divide(tot)); } } }