失败的代码。。。不过思路是对的

/*
    树的 prufer数列
    一棵树有唯一的prufer数列 长度为 节点n-2
    一个prufer数列 有唯一的一棵树 大小为 长度 l+2 
    优质博客: 
    https://blog.csdn.net/sleepiest/article/details/81558924
    对于确定的和不确定的分别求解 然后乘法原理
    
    确定的 首先判断能否成树 
    根据prefer数列原理? sigma(di-1)不能超过 n-2 
    然后就是博客里面的组合数+乘法原理
    
    不确定的 prufer数列还剩下  k=n-2-sigma(di-1) 空位
    此时可以吧不确定的点任一放进去 
    有 (不确定节点数)^(剩下空位) 组合方案数 
    排列公式里面有阶乘  可以质因数分解 约分 算出答案 
    这里用高精 不过调了很久都没过。。干脆不做了 
*/
#include<cstdio> 
#include<cstring>
#define ll long long
using namespace std;
const int N=1050;
struct BigInt
{
    int num[10000],len;

    BigInt()
    {
        memset(num,0,sizeof(num));
        len=1;
    }

    BigInt operator* (const int &rhs) const
    {
        BigInt ans;
        ans.len=len+6;
        for (int i=1;i<=len;i++)
            ans.num[i]+=num[i]*rhs;
        for (int i=1;i<ans.len;i++)
            if (ans.num[i]>9)
            {
                ans.num[i+1]+=ans.num[i]/10;
                ans.num[i]%=10;
            }
        while (!ans.num[--ans.len])
        return ans;
    }

    BigInt operator/ (const int &rhs) const
    {
        BigInt ans=*this;
        ans.len++;
        for (int i=ans.len;i;i--)
        {
            ans.num[i-1]+=ans.num[i]%rhs*10;
            ans.num[i]/=rhs;
        }
        while (!ans.num[--ans.len]);
        return ans;
    }
    void print()
    {
        while (!num[--len]);
        for(int i=len;i;i--) printf("%d",num[i]);printf("\n");
    }
}res;
int n,d[N],rest,all,top;
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&d[top+1]);
        if(d[top+1]==-1) continue;
        top++;all+=d[top]-1;
        if(!d[top]) {puts("0");return 0;} 
    }
    if(all>2*n-2) {puts("0");return 0;} // 无解 
    res.num[1]=1;
    for(int i=n-1-all;i<=n-2;i++) res=res*i;
    for(int i=1;i<=n-2-all;i++) res=res*(n-top);
    for(int i=1;i<=top;i++)
    {
        for(int j=2;j<=d[i]-1;j++) res=res/j;
    }
    res.print();
    return 0;
}