A - PRO-Professor Szu
简单的来说就是 缩点、反图拓扑。
需要注意不与 n + 1 n+1 n+1 联通的点可能会使得一些点的入度无法为 0 而无法入队,消除这些点的影响即可。
当时写的:
D - BLO-Blockade
非割点: 2 ( n − 1 ) 2(n-1) 2(n−1)。
割点:删去割点会将图划分为若干个连通块,不重复地计算这些连通块之间的方案数即可。
G - 杀人游戏
水题。
很容易想到缩点之后找入度为 0 0 0 的点。
注意一下特殊的点,如孤立点,或者是入度为 0 0 0 且指向的点都有别的点指向他(认识的人都有被其他至少一人认识)。
H - 建造军营
关于状态设计:
以 u u u 为根的子树截答案结构是什么?设计 f u f_u fu 表示以 u u u 为根的子树中有军营的方案数,其中建造的军营与 u u u 之间的边都被保护。设计 g u g_u gu 表示以 u u u 为根子树中没有军营的方案数(也可以根据点数推, g g g 辅助作用)。
记 V u , E u V_u,E_u Vu,Eu 为边双树上点 u u u 的点数和边数
初始值 g u = 2 E u g_u = 2^{E_u} gu=2Eu, f u = 2 V u + E u − g u f_u=2^{V_u+E_u}-g_u fu=2Vu+Eu−gu。
对于 f u f_u fu 的转移可以考虑儿子 v v v 的贡献:
- v v v 之前子树非空, v v v 可以空或非空,贡献为 f u ← f u × ( 2 × g v + f v ) f_u \larr f_u \times (2\times g_v+f_v ) fu←fu×(2×gv+fv)。
- v v v 之前子树空, v v v 必不空,贡献为 f u ← f u + g u × f v f_u \larr f_u + g_u \times f_v fu←fu+gu×fv(这里 g u g_u gu 是在考虑 v v v 之前)。
对于 g u g_u gu 的转移: g u = ∏ ( 2 × g v ) g_u = \prod (2\times g_v) gu=∏(2×gv)。
得到具体的 f f f 值后,考虑如何统计答案: f v f_v fv 可以确定子树内的情况,子树外需要通过设计使得每个 f f f 不会重复计算。
我们发现在确定 f v f_v fv 后,若不选 v → u v \to u v→u,则这样的方案一定不在 f u f_u fu 中。每个点都统计不选到父亲的边的方案数 a n s i ans_i ansi,可以保证每个点这样的方案数互不重叠。记 s i z siz siz 表示子树内总边数,则子树外有 2 m − s i z v − 1 2^{m-siz_v-1} 2m−sizv−1 种方案, a n s v = f v × 2 m − s i z v − 1 ans_v=f_v \times 2^{m-siz_v-1} ansv=fv×2m−sizv−1。特别的,对于 1 1 1 号点, a n s 1 = f 1 ans_1 = f_1 ans1=f1。
最终方案数即为 ∑ a n s i \sum ans_i ∑ansi。