【题解】UOJ#37. [清华集训2014]主旋律
我自己写的代码自己都看不懂。
所以芝士一种船新做法,爱来自学弟,lc 学长好工作。
题意
校内 OJ 的题面过于简洁,人话:
给定一个有向的强连通图,问任意删边使得新图仍强连通的方案总数。
答案对 \(10^9 + 7\) 取模。
思路
状压 dp + 容斥。
\(n \leq 15\) 一眼鉴定为状压,令 \(f_S\) 表示点集为 \(S\) 的强连通生成子图数。
考虑到强连通图按强连通分量缩点之后是 DAG,考虑 DAG 的经典套路是钦定出度为 \(0\) 的点进行计数。
只依靠 \(f\) 还是不好转移,考虑容斥成所有方案数减去不强连通的方案数。
令 \(g_S\) 表示点集为 \(S\) 且不强连通的生成子图数,当然后面的 \(g_S\) 还要改定义。
钦定 \(T\) 表示 \(S\) 构成的生成子图中,缩点后出度为 \(0\) 的强连通分量构成的点集。
考虑 \(f, g\) 的直觉转移和一些等量关系:
对于任意的生成子图,考虑如何钦定原图的若干强连通分量得到它:
令 \(E(S, T)\) 表示 \(\sum\limits_{(u, v) \in E} [u \in S, v \in T]\).
先钦定 \(T\) 中的结点分裂成多个强连通分量。
属于 \(S - T\) 的结点之间任意连边,方案数是 \(2^{E(S - T, S - T)}\).
这些结点和 \(T\) 中的结点也任意连边,方案数是 \(2^{E(S - T, T)}\).
有 \(2^{E(S, S)} = \sum\limits_{T \in S} g_T 2^{E(S - T, S - T)} 2^{E(S - T, T)}\).
\(g\) 的转移似乎只需要钦定图中强连通分量的构成:
\(g_S = \sum\limits_{s_1, \cdots, s_k} \prod\limits_{i = 1}^k f_{s_k}\),其中 \(s_1, \cdots, s_k\) 两两不交并且并集为 \(S\),表示 \(S\) 的一种划分.
然而 \(2^{E(S - T, S - T)}\) 种方案中可能有更多出度为 \(0\) 的强连通分量,所以上面都会算重。
于是考虑容斥去重:
\(g_S = \sum\limits_{s_1, \cdots, s_k} (-1)^{k + 1} \prod\limits_{i = 1}^k f_{s_k}\).
钦定此时 \(g\) 中不包含只有 \(S\) 一个强连通分量的情况。
大体证明考虑二项式反演,见 lcw 的博客。
考虑代回到和 \(g\) 有关的式子中:\(2^{E(S, S)} = \sum\limits_{T \in S} g_T 2^{E(S - T, S - T)} 2^{E(S - T, T)}\).
也就是 \(g_S = 2^{E(S, S)} - \sum\limits_{T \in S} g_T 2^{E(S - T, S - T)} 2^{E(S - T, T)}\).
得到 \(g\) 的递推式。
\(f\) 不好做,就用 \(g\) 推 \(f\).
观察联系 \(g, f\) 的式子 \(g_S = \sum\limits_{s_1, \cdots, s_k} (-1)^{k + 1} \prod\limits_{i = 1}^k f_{s_k}\).
进一步化简,只需钦定其中编号最小的点所在的强连通分量,剩下的部分在更小规模的状态算过:\(g_S = - \sum\limits_{s_1 \subseteq S, s_1 \neq \emptyset} f_{s_1} g_{S - s_1}\).
把 \(s_1 = S\),也就是 \(f_S\) 的情况提出来,化简一下得到 \(f_S = g_S + \sum\limits_{s1 \subsetneq S, s_1 \neq \emptyset} f_{s1} g_{S - s_1}\).