1005: [HNOI2008]明明的烦恼
Time Limit: 20 Sec
Memory Limit: 256 MB
题目连接
http://www.lydsy.com/JudgeOnline/problem.php?id=1005
Description
自从明明学了树的结构,就对奇怪的树产生了兴趣…… 给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少棵度数满足要求的树?
Input
第一行为N(0 < N < = 1000),接下来N行,第i+1行给出第i个节点的度数Di,如果对度数不要求,则输入-1
Output
一个整数,表示不同的满足要求的树的个数,无解输出0
Sample Input
3
1
-1
-1
Sample Output
2
HINT
题意
题解:
实际上就是让你求,有多少种Purfer序列
理解Purfer序列之后,这就是排列组合题了
这篇博文写的非常精彩:http://www.cnblogs.com/zhj5chengfeng/archive/2013/08/23/3278557.html
代码:
import java.util.*; import java.math.*; public class Main { static int n, d[]=new int[10002]; static BigInteger p[]=new BigInteger[1002]; static BigInteger ans; static public void main(String args[]) { Scanner IN=new Scanner(System.in); n=IN.nextInt(); int sum=0, flag=0, cnt=0; for(int i=0; i<n; i++) { d[i]=IN.nextInt(); if(d[i]==0 || d[i]>n-1) flag=1; if(d[i]==-1) continue; sum+=d[i]-1; cnt++; } IN.close(); if(n==1) { if(d[0]==0 || d[0]==-1) System.out.println(1); else System.out.println(0); return; } if(n==2) { if((d[0]==-1 || d[0]==1) && (d[1]==-1 || d[1]==-1)) System.out.println(1); else System.out.println(0); return; } if(flag==1) System.out.println(0); p[0]=BigInteger.ONE; for(int i=1; i<=n; i++) p[i]=p[i-1].multiply(BigInteger.valueOf(i)); ans=p[n-2].divide(p[n-2-sum]); for(int i=0; i<n; i++) { if(d[i]==-1) continue; ans=ans.divide(p[d[i]-1]); } for(int i=0; i<n-2-sum; i++) ans=ans.multiply(BigInteger.valueOf(n-cnt)); System.out.println(ans); } }