注意到把边当成无向边就是棵树,以下提到这棵树的地方将会加上「」以区分。
考虑设 fu,i 表示「以 u 为根的子树」的导出子图的所有拓扑序列中,u 放在第 i 位的方案数。
转移时考虑增加一个儿子 v 的贡献,设 f′u,i 表示增加 v 的贡献之后的 f。
若 v 必在 u 之前,枚举 u 原来的排名 j 和 v 原来的排名 k,则需从「以 v 为根的子树」中取 i−j 个放在 u 之前(必包含 v),有 f′u,i=min(i−1,sizeu)∑j=1i−j∑k=1fu,jfv,k(i−1j−1)(sizeu+sizev−isizeu−j)
其中 sizeu 表示「v 之前的子树」的大小,sizev 表示「以 v 为根的子树」的大小。
注意到这是一个 O(n3) 的转移,然而用前缀和优化即可。
v 在 u 之后的限制类似。
代码:
1 |
|