nowcoder20065 [HNOI2008]明明的烦恼

链接

点击跳转

p r u f e r prufer prufer序列

p r u f e r prufer prufer序列与无根树一一对应,一棵包含 n n n个节点的无根树,对应一个包含 n − 2 n-2 n2个元素的 p r u f e r prufer prufer序列

求无根树的 p r u f e r prufer prufer序列

重复进行以下操作,直至树中只剩下两个点:

  • 找到一个度数为1,且编号最小的点。
  • 把这个点的父亲节点加入序列,然后把这个点从树中删除。

p r u f e r prufer prufer序列所表示的无根树

我重复进行以下操作,直至点集中只剩下两个点:(初始化所有点都在点集中)

  • 取出prufer序列最前面的元素x。
  • 取出在点集中的、且当前不在prufer序列中的最小元素y。
  • 在x,y之间连接一条边。(注意前面的取出相当于删除)

最后,我们在点集中剩下的两个点中连一条边。

相关结论

  • p r u f e r prufer prufer序列与无根树一一对应。
  • 度数为 d i d_i di的节点会在prufer序列中出现 d i − 1 d_i−1 di1次。
  • 一个 n n n个节点的完全图的生成树个数为 n n − 2 n^{n−2} nn2
  • 对于给定度数的一棵无根树共有 ( n − 2 ) ! ∏ i = 1 n ( d i − 1 ) ! \frac{(n−2)!}{\prod^n_{i=1}(d_i−1)!} i=1n(di1)!(n2)!种情况。

题解

这题就是固定了某些元素的出现次数,问你一共有多少种序列

很简单的计数题

代码

maxn = 1010
n = int(input())
deg = []
free = 0
for i in range(n):
    d = int(input())
    if d==-1: free+=1
    else: deg.append(d-1)
fact = []
for i in range(maxn):
    if i==0: fact.append(1)
    else: fact.append(fact[-1]*i)
tot = sum(deg)
ans = fact[tot]
for x in deg: ans //= fact[x]
ans *= fact[n-2]//fact[tot]//fact[n-2-tot]
for i in range(n-2-tot):
    ans *= free
print(ans)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值