图上的状压dp
图上的状压dp
1.树与仙人掌
Problem A. 给定一张无向图,有多少种保留边生成一棵树的方案
解法1:容斥
设 \(f_S\) 为点集为 \(S\) 的方案数。
枚举真子集 \(T\) 作为叶子,则有转移 \(f_{S} \leftarrow f_{S \setminus T}\times g_{S \setminus T,T}\),其中 \(g_{x,y}\) 表示点集 \(x\) 向点集 \(y\) 连边的数量。
但此时会算重复,因为集合 \(S\setminus T\) 中也有一些点是叶子。
那么考虑容斥:\(f_S=\sum_{\varnothing \subset T \subset S} f_{S \setminus T}\times g_{S \setminus T,T} \times(-1)^{|T|-1}\)。
解法2: lowbit 计数
设 \(lb(S)\) 为集合 \(S\) 内编号最小的点。
钦定 \(lb(S)\) 为点集 \(S\) 的根,把其他的点集作为一个子树接在 \(lb(S)\) 上。
设 \(x=lb(S),S' = S\setminus\{s\}\)。为了避免重复计数,我们每次只考虑考虑 \(lb(S')\) 在哪一棵子树里,有转移:\(f_{S} = \sum_{\varnothing \subset T \subseteq S' \land lb(S')\in T} f_{S\setminus T} \times f_T \times g_{x,T}\)。
Problem B. 给定一张无向图,有多少种保留边生成一个边仙人掌的方案
类似于树,我们把点集 \(S\) 的 “根” 钦定为 \(lb(S)\),每次将一棵子树 \(T\) 接在根上。同样要求 \(lb(S') \in T\)。
有两种转移,\((lb(S),T)\) 这条边是否在环内。设 \(h_{i,j,S}\) 为链的起点、终点与点集分别为 \(i,j,S\) 的方案,列出转移:
- \(f_{S} \leftarrow f_T \times f_{S\setminus T } \times g_{x,T}\);
- \(f_{S} \leftarrow f_{S \setminus T} \times h_{i,j,T} \times [(x,i)\in E] \times [(x,j)\in E]\)。
- \(h_{i,i,S} \leftarrow f_{S} \times [i \in S]\);
- \(h_{i,j,S} \leftarrow h_{i,k,{S\setminus T}} \times f_{T}\ \times [(k,j)\in E] \times [j \in T]\)。
2. DAG
Problem A. 给定一张有向图,有多少种保留边生成一个 DAG 的方案
类似于树的容斥解法,每次枚举一个点集 \(T\) 作为出度为 \(0\) 的点接上去。
同样有容斥:\(f_S=\sum_{\varnothing \subset T \subset S} f_{S \setminus T}\times 2^{|E(S\setminus T \rightarrow T)|} \times(-1)^{|T|-1}\)。
Problem B. [ABC306Ex] Balance Scale
如果不考虑等号,就是求给无向图的每条边定向生成 DAG 的方案数。此时 \(T\) 的元素之间两两不能有连边。
加上等号,等号相当于合并了两端的点。称合并完毕的极大子图为 “块”,那么可以转变为枚举新的块集 \(T\)。
我们不再要求 \(T\) 两两无边。设 \(c_T\) 为 \(T\) 集合的块个数,那么容斥系数变为 \((-1)^{c_T-1}\)。
用并查集可以预处理出每个 \(c_S\)。
Problem C. [CF1556F] Sports Betting
由期望的线性性,答案等价于每个人成为 winner 的概率之和。设 \(f_{i,S}\) 为 \(i\) 打败 \(S\) 的概率。
首先有一个比较 naive 的转移:枚举点集 \(S\) 下一个打败的人 \(x\),转移到 \(f_{S \cup \{x\}}\)。
但此时会算重,因为从 \(S\) 转移到超集 \(T\) 有很多种方式,但它们都是本质相同的,而且我们无法钦定一个较好的转移顺序使得其不重复。
不如使用容斥。假如未能战胜 \(S\) 的概率为 \(P\),那么战胜的概率就是 \(1-P\)。
枚举是哪些 “硬骨头” \(T\) 无法被战胜,有转移:\(P \leftarrow f_{S\setminus T} \times g_{S \setminus T,T}\),其中 \(g_{x,y}\) 表示 \(x\) 的每一个元素都没有战胜 \(y\) 的概率。
3. 强连通图
Problem A. 给定一张有向图,有多少种保留边生成一个强连通图的方案
一张有向图是强连通图,当且仅当其只有一个 SCC。
考虑容斥,类似于 DAG 计数。设 \(f_{S}\) 为 \(S\) 为强连通图的方案数。
我们枚举 \(S\) 的子集 \(T\) 作为出度为 \(0\) 的 SCC 的并集,\(T\) 中可以包含多个 SCC,\(S\setminus T\) 中可以任意连边。
但这样会算重,因为 \(S\setminus T\) 中也可能有出度为 \(0\) 的 SCC。
所以如果 \(T\) 中含有 \(i\) 个 SCC,那么这个方案被统计时需要带上 \((-1)^{i-1}\) 的系数。
我们接着设 \(g_S\) 为 \(S\) 内包含多个不互相连边的 SCC,且带上了 $(-1)^{i-1} $ 的系数的方案数。
特别地,\(g_0=-1\)。
- \(g_S=-\sum_{lb(S)\in T\subseteq S}f_T\times g_{S\setminus T}\);
- $ f_S=2^{|E(S)|}- \sum_{\varnothing \subset T\subseteq S}g_T\times2^{|E(S\setminus T)|+|E(S\setminus T \rightarrow T)|}$。
此时会出现 \(f_S,g_S\) 相互转移的情况。
冷静一下,\(f_S\) 转移到了自己是不合法的,因为 \(f_S\) 本身是合法的,不应减去。
那么我们先不让 \(f_S\) 转移到 \(g_S\),计算出 $g_S $,再计算 \(f_S\),最后将 \(g_S\) 加上 \(f_S\) 即可。
Problem B. 给定一张有向图,每条边有可正可负边权,保留边权和尽量大的边使得新图强连通
由于是最优化问题,我们不需要考虑转移是否会重复。
考虑对于一个强连通图 \(S\),我们将一条链 \(T\) 接到 \(S\) 的两个点上,新图仍然强连通。
这样我们可能会漏掉一些边,例如链 \(T\) 上还可以多选择一些边生成若干个环。
我们不如先将边权 \(\geq 0\) 的边全部选上,然后令它们的边权变为 \(0\),再考虑负权边就是正确的了。
设 \(f_S\) 为使得 \(S\) 为强连通图的最大边权和,\(g_{i,j,S}\) 为链的起点、终点为 \(i,j\),总点集为 \(S\) 的最大边权和。
- \(g_{i,j,S} \leftarrow g_{i,k,S\setminus \{j\}}+w(k\rightarrow j)\)
- $f_{S} \leftarrow g_{i,i,S} $;
- \(g_{i,j,S} \leftarrow f_S \ (i\in S\land j \in S)\)。
复杂度为 \(O(2^n \times n^2)\),比计数问题更优。
4. 无向图连通性
Problem A. 给定一张无向图,有多少种保留边生成连通图的方案
仍然考虑容斥。设 \(f_S\) 为使得 \(S\) 连通的方案数。
我们用总方案数减去使得连通块个数 \(>1\) 的方案数。
枚举 \(lb(S)\) 所在的连通块 \(T\),有转移:\(f_{S} = 2^{|E(S)|} - \sum_{lb(S)\in T\subset S} f_T \times 2^{|E(S \setminus T)|}\)。
Problem B. 给定一张无向图,有多少种保留边生成点双连通图的方案
设 \(f_{i,S}\) 为使得点集 \(S\) 割点编号全部 \(\leq i\) 的方案数。答案为 \(f_{0,AS}\)。
\(f_{n,S}\) 就是问题 A 种求出的答案。考虑如何计算 \(i<n\) 的答案。
首先有 \(f_{i,S}=f_{i+1,S} \ (i \notin S)\)。
其他情况下,若 \(i\) 为割点,去掉 \(i\) 这个点后 \(S\) 会被分为若干个连通块。设 \(S'=S\setminus \{i\}\)。
枚举 $lb(S') $ 所在的连通块 \(T\),那么 \(T\) 中 \(i\) 不允许为割点。由于可能有多个连通块,\(S\setminus T\) 中 \(i\) 仍然可能为割点。
有转移:\(f_{i-1,S}=f_{i,S}-\sum_{lb(S')\in T\subset S'} f_{i-1,T\cup\{i\}}\times f_{i,S\setminus T}\)。

浙公网安备 33010602011771号