【BZOJ1211】【HNOI2004】树的计数 prufer序列

题目描述

  给你(n)(n)个点的度数,问你有多少个满足度数要求的生成树。

  无解输出(0)。保证答案不超过({10}^{17})

  (nleq 150)

题解

  考虑prufer序列。

  答案为

[frac{(n-2)!}{prod(d_i-1)!} ]

  直接乘会爆long long,要转成(n-1)个组合数的乘积。当然你也可以分解质因数。

  如果(n eq 1)(d_i=1),输出(0)

  如果(sum d_i eq 2n-2),输出(0)

  时间复杂度:(O(n^2))

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<utility>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
ll c[200][200];
int d[200];
int main()
{
	int n;
	scanf("%d",&n);
	int i,j;
	int sum=0;
	for(i=1;i<=n;i++)
	{
		scanf("%d",&d[i]);
		if(n!=1&&d[i]<=0)
		{
			printf("0
");
			return 0;
		}
		sum+=d[i];
	}
	if(sum!=2*n-2)
	{
		printf("0
");
		return 0;
	}
	for(i=0;i<=n;i++)
	{
		c[i][0]=1;
		for(j=1;j<=i;j++)
			c[i][j]=c[i-1][j]+c[i-1][j-1];
	}
	ll ans=1;
	ll s=0;
	for(i=1;i<=n;i++)
	{
		ans*=c[s+d[i]-1][d[i]-1];
		s+=d[i]-1;
	}
	printf("%lld
",ans);
	return 0;
}
原文地址:https://www.cnblogs.com/ywwyww/p/8512247.html