【洛谷2624】[HNOI2008] 明明的烦恼(Python+利用prufer序列结论求解)

点此看题面

大致题意: 给你某些点的度数,其余点度数任意,让你求有多少种符合条件的无根树。

(prufer)序列

一道弱化版的题目:【洛谷2290】[HNOI2004] 树的计数

这同样也是一道利用(prufer)序列求解的题。

还是考虑到由(prufer)序列得到的结论:对于给定度数为(d_{1sim n})的一棵无根树共有(frac{(n-2)!}{prod_{i=1}^n(d_i-1)!})种情况

但这次就不能直接套公式了。

推式子

考虑对于已知度数的点,设其个数为(k),且(d_i-1)的和为(s)

然后对于这些已知的点,我们易得方案数为:

[frac{s!}{prod_{i=1}^k(d_i-1)!} ]

由于这(k)个点可以任选,因此还需乘上一个组合数,得到:

[C_{n-2}^kcdotfrac{s!}{prod_{i=1}^k(d_i-1)!} ]

则剩下的(n-2-s)个位置是可以任意排列的,而又共有(n-k)个点,因此总方案数为:

[C_{n-2}^kcdotfrac{s!}{prod_{i=1}^k(d_i-1)!}*(n-k)^{n-2-s} ]

然后就可以直接算了。

求解答案

(Python)大法好,无需高精度除法,也无需质因数分解(23333)

代码

n=(int)(input());k=0;s=0;a=[0 for i in range (n+5)];#初始化
for i in range(1,n+1):
    a[i]=(int)(input());
    if a[i]==0:print(0);exit();#判断无解
    if a[i]!=-1:k+=1;s+=a[i]-1;#统计k与s
if s>n-2:print(0);exit();#判断无解
f=[0 for i in range(n+5)];f[0]=1;#建立阶乘数组
for i in range(1,n+1):f[i]=f[i-1]*i;#预处理阶乘
ans=ans=(f[n-2]//f[s]//f[n-2-s])*f[s];#初始化ans为C(n-2,s)*s!
for i in range(1,n+1):
    if a[i]!=-1:ans//=f[a[i]-1];#计算答案
print(ans*pow(n-k,n-2-s));#计算答案

原文地址:https://www.cnblogs.com/chenxiaoran666/p/Luogu2624.html