如果独自去想出prufer序列实在太难了
所以就只能直接用结论,把树转成prufer序列后这棵树和prufer序列是一一对应的关系
树->prufer序列:每次找到所有叶子结点中编号最小的,删掉,然后把他的父亲加入序列
prufer序列->树:新建一棵树,当前还没有节点,从前往后,找到当前序列中没有,新建的树上也没有的数中最小的,和序列头连边,然后头指针++,
所以就变成了数字分配问题,直接组合数就可以了
码:
#include<iostream>
#include<cstdio>
using namespace std;
long long n,i,d[160],c[160][160],o,ans=1,j;
int main()
{
scanf("%lld",&n);
for(i=1;i<=n;i++)
{
scanf("%lld",&d[i]);
o+=d[i]-1;
if(d[i]==0&&n!=1){
printf("0");
return 0;
}
}
if(n==1&&d[1]==0)
{
printf("1");
return 0;
}
if(o!=n-2){
printf("0");
return 0;
}
c[0][0]=1;
for(i=1;i<=n;i++)
{c[i][0]=1;
for(j=1;j<=i;j++)c[i][j]=c[i-1][j-1]+c[i-1][j];
}
o=n-2;
for(i=1;i<=n;i++)
{
ans*=c[o][d[i]-1];
o-=(d[i]-1);
}
printf("%lld",ans);
}