题目传送门:https://www.luogu.org/problemnew/show/P2290
题意:
有n个点,每一个点的度分别为di,求可以组成的一棵无根树的方案数。
思路:
prufer序列性质4的裸题。
详见我的blog:prufer序列
有一些坑点:
[1]如果某一个点的度为0,并且不止一个点,一定无解(因为这样子就会有一棵以上的树,不符合题意)。
[2]如果不满足prufer序列性质2,也无解。
代码:
#include<cstdio>
#include<cmath>
#include<algorithm>
#define LL long long
using namespace std;
int n,ma=0;
int d[200],a[1000000];
LL ans=1;
void work(int x,int y)
{
int p=sqrt(x);
for(int i=2;i<=p;i++)
{
while(!(x%i)) ma=max(ma,i),x/=i,a[i]+=y;
if(x==1) return;
}
if(x!=1) ma=max(ma,x),a[x]+=y;
}
int main()
{
int sum=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&d[i]);
if(n>1&&!d[i])
{
printf("0");
return 0;
}
sum+=d[i]-1;
}
if(sum!=n-2)
{
printf("0");
return 0;
}
for(int i=1;i<=n-2;i++)
work(i,1);
for(int i=1;i<=n;i++)
for(int j=1;j<d[i];j++)
work(j,-1);
for(int i=1;i<=ma;i++)
ans*=pow(i,a[i]);
printf("%lld",ans);
}