[BZOJ1211 & 洛谷P2290] [HNOI2004]树的计数-【Purfer序列】py+Java

题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1211   

洛谷:https://www.luogu.com.cn/problem/P2290

Time Limit: 10 Sec  Memory Limit: 162 MB
洛谷:时间限制1.00s 内存限制125.00MB

Description

一个有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

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));
        }
    }
}

 

 
posted @ 2020-01-13 20:51  lonely_wind  阅读(175)  评论(0编辑  收藏  举报