题目:
给出一棵边有方向的树,求该图的拓扑序数量。
n≤103
题解:
先将这玩意当做普通的树来做。
设 fu,i 表示节点 u 在子树中的排名为 i 的方案数。
那么考虑类似于树形背包,将 v 加入子树 u 来转移。
- v 连向 u。
所以 u 拓扑序比 v 大。
设 u 原来的排名为 p,v 原来在其子树中的排名为 q。
设 fu′,k 为 u 加入 v 这棵子树后 u 排名为 k 的方案。
那么 v 中就必然有 k−p 个节点的拓扑序比 u 小。而 v 的排名比 u 前。
所以转移的限制是 q≤k−p 即 p+q≤k。
考虑现在比 u 小的节点有 k−1 个,原来比 u 小的有 p−1 个,显然这些点是确定的,所以只需要考虑顺序,方案数为 (k−1p−1)。那么剩下比 u 排名大的同理方案数为 (szu+szv−kszu−p)。
所以可得转移为
fu′,k=szu∑p=1szv∑q=1[p+q≤k]fu,pfv,q(k−1p−1)(szu+szv−kszu−p)
- u 连向 v。
与第一种同样的方法。
直接上转移:
fu′,k=szu∑p=1szv∑q=1[p+q>k]fu,pfv,q(k−1p−1)(szu+szv−kszu−p)
考虑优化。
先提出 p:
fu′,k=szu∑p=1fu,p(k−1p−1)(szu+szv−kszu−p)k−p∑q=1fv,q
fu′,k=szu∑p=1fu,p(k−1p−1)(szu+szv−kszu−p)szv∑q=k−p+1fv,q
发现直接搞一个前缀和就好了。
设 su,i 为 fu,i 的前缀和。
fu′k=szu∑p=1fu,p(k−1p−1)(szu+szv−kszu−p)sv,q
fu′k=szu∑p=1fu,p(k−1p−1)(szu+szv−kszu−p)(sszv−sk−p)
时间复杂度 O(n2)。
本文作者:trsins
本文链接:https://www.cnblogs.com/trsins/p/15815374.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步