宽体树图
翘课唐完了。下次不翘了。
树形 DP 依赖于删去树根后,树分裂为若干子树;换言之,在处理一些与树上邻接性相关的信息时,只需传入树根一者的状态即可进入子树处理。
显然我们可以不止传入一个信息。我们希望找到一个阈值 \(w\),使得我们可以递归式地为每个状态传入至多 \(w\) 个信息,进入子问题。
这就是我们有界树宽问题。
定义:一张图 \(G=(V,E)\) 的树分解是满足如下条件一棵树 \(T\),\(T\) 上每个节点 \(t\) 都放置了一个集合 \(V_t\),且:
- \(V\) 中每个节点被至少一个 \(V_t\) 包含。
- \(V\) 中每条边的两端点至少被一个 \(V_t\) 同时包含。
- \(V\) 中每个节点被 \(V_t\) 包含的全体 \(t\) 构成连通块(换言之,如果 \(t_1,t_2\) 都包含 \(x\),那么二者路径中的每个 \(t\) 均包含 \(x\))
对于 \(T\) 上一个节点集合 \(T'\),定义 \(G_{T'}\) 为 \(T'\) 中全体节点 \(V_t\) 的并集的导出子图。
树分解满足如下性质:
- 对于树上每个节点 \(t\),删去 \(t\) 后树分成若干块 \(T_1,\dots\),则全体 \(G_{T_i}\setminus V_t\) 两两无交、且不相邻。
- 对于每条边 \((s,t)\),删去后树分成两块 \(T_1,T_2\),则 \(G_{T_i}\setminus\{V_s\cap V_t\}\) 无交、不相邻。
第一条性质:假设有交,不妨令 \(T_1\) 中的点 \(t_1\) 的 \(V_{t_1}\) 和 \(T_2\) 中 \(t_2\) 的 \(V_{t_2}\) 同时含 \(x\notin V_t\),则 \(t\) 在 \(t_1\) 至 \(t_2\) 的路径上,因此必须包含 \(x\),则 \(x\in V_t\),不合法;假设有边 \(x,y\),则 \(x\) 在 \(T\) 中的分布连通块显然不能过 \(t\),\(y\) 同理,于是它们不可能在同一个 \(V_t\) 内共存,\((x,y)\) 边未被任何 \(V_t\) 同时包含。
第二条性质同理。
一个树分解对应的树宽即为 \(\max|V_t|-1\)。一个图的树宽为全体树分解中最小树宽。子图的树宽必然不超过母图。
一个非冗余 (nonredundant) 的树分解是任意相邻两点 \(s,t\) 不存在一个的 \(V\) 包含另一个的场合。通过重复将被包含的那个点缩到更大的点上,一个冗余树分解必然可以在不改变树宽的前提下变成非冗余树分解。通过不断剥叶子,可以证明非冗余树分解的点数必然不超过原图的点数。
如何求出一张图的树宽?这其实是 NP-Hard 的。但是,给定一个阈值 \(w\),构造一个树宽小于 \(4w\) 的树分解或判定树宽必然大于等于 \(w\),这件事情是可以在与 \(w\) 有关的复杂度(具体而言,\(f(m)\cdot mn\))内解决的。
如何判定树宽?
定义:两个包含相等数目节点的集合 \(Y,Z\) 是可分 (separable) 的,若它们间的最小割点集的大小严格小于二者共同的节点数目。即,存在集合 \(X\) 满足 \(|X|<|Y|=|Z|\),且 \(Y\setminus S\) 与 \(Z\setminus S\) 在 \(G\setminus S\) 上不连通。【注意,这并不要求 \(Y,Z\) 无交】
定义:一个集合 \(X\) 被称作 \(w\)-连接 (\(w\)-linked) 的,如果 \(|x|\geq w\) 且其中所有子集 \(|Y|=|Z|\leq w\) 都是不可分的。
可以在 \(f(|X|)m\) 的复杂度内判定一个集合 \(X\) 是否是 \(w\)-连接的;如果不是,该算法同时可以找到可分集合对 \((Y,Z)\) 和它对应的割点集 \(S\)。
方法很简单:全体 \(Y,Z\) 对共有不超过 \(4^{|k|}\) 对;每一对相当于求最小割,因此在 \(|Y|m\) 的复杂度内即可判定是否可分。
定理:存在大小至少为 \(3w\) 的 \(w+1\)-连接集合意味着树宽至少为 \(w\)。
假设存在非冗余的树分解 \(T\) 满足全体 \(|V_t|\leq w\),同时存在 \(w+1\)-连接、大小至少为 \(3w\) 的集合 \(X\)。
令树是有根树。令 \(G_t\) 为树上节点 \(t\) 子树中全体点对应的 \(G_T\)。考虑从根往下能走就走,直到某点 \(t\),满足 \(G_t\) 包含超过 \(2w\) 个 \(X\) 中元素,但其全体儿子均不然。
显然 \(t\) 不是叶子(否则 \(G_t=V_t\),而 \(|V_t|\leq w\))。令其有儿子们 \(t_1,\dots,t_d\)。
假如存在一个包含至少 \(w\) 个 \(X\) 中元素的儿子 \(t_i\),则从中挑出 \(w\) 个作为 \(Y\),从 \(G-G_{t_i}\) 中挑出 \(w\) 个作为 \(Z\)。因为非冗余,所以 \(|V_t\cap V_{t-1}|<w\),而删去 \(V_t\cap V_{t-1}\) 后,\(Y\) 与 \(Z\) 就此分别,于是 \(Y,Z\) 可分,违背了 \(X\) 是 \(w+1\) 连接的前提。
假如不存在这样的儿子,那么考虑用多个儿子组合起来,直到 \(G_{t_{1\sim p}}\) 中包含严格超过 \(w\) 个 \(X\) 中元素,则其必然严格小于 \(2w\) 个。于是从其内部挑 \(w+1\) 个,再从外部挑 \(w+1\) 个,删光 \(V_t\) 即可将它们分割。
算法:给定一个阈值 \(w\),构造一个树宽小于 \(4w\) 的树分解或判定存在大小至少 \(3w\) 的 \(w+1\)-连接集合。
维护一个部分树分解:我们如今已构造了若干 \(V_t\);它们应恰好成为 \(G\) 的某个子集(即全体 \(V_t\) 并集 \(U\))诱导子图的树分解。我们需要保证部分树分解中全体 \(|V_t|\leq4w\)。
\(G\setminus U\) 由若干连通块组成,它们是相对独立的。一个连通块 \(C\) 拥有邻居 \(u\in U\),如果 \(u\) 与 \(C\) 中某一元素 \(v\) 相邻。
在维护部分树分解的过程中,同时维持一条额外性质,即任意时刻,每个 \(C\) 至多有 \(3w\) 个邻居,这些邻居由同一个 \(V_t\) 储存(即 \(C\) 中诞生的新状态的父亲)。这样,每次递归就是从 \(C\) 中挑出不超过 \(w\) 个元素,把它与这不超过 \(3w\) 个邻居放一块搞出来,作为 \(V_t\) 的儿子连出来。
如果邻居确实不够 \(3w\) 个,那再多一个也没事。于是从 \(C\) 中随便挑一个,把它和这不足 \(3w\) 个邻居放一块诞生子状态,则 \(C\) 分裂(不一定发生)出的所有子状态的邻居集合至多多一个新增元素,因此这样做合法。
现在邻居恰有 \(3w\) 个,记为集合 \(X\)。首先可以跑一边 \(w+1\)-连接集合验证算法,判定邻居集合是否是 \(w+1\)-连接的,如果是那么 \(G\) 的树宽显然大于 \(w\)。否则其并非 \(w+1\) 连接的,存在两个集合 \(Y,Z\),通过删去某个 \(S\) 而不连通。
因为 \(Y,Z\) 各自都与 \(C\) 中有边,所以 \(S\) 不可能不含 \(C\) 中元素。取 \(S'=S\cap(Y\cup Z\cup C)\),则 \(S'\not\subseteq X\) 且 \(|S'|\leq w\)。令 \(S'\cup X\) 为 \(V_s\) 作为 \(V_t\) 的儿子,则其合法,因为:
令 \(S''\) 为 \(S'\) 中剔除 \(X\) 中元素的部分。则 \(C\setminus S''\) 中的每个元素关于与 \(Y,Z\) 是否联通,分成两个集合,每个集合的邻居集合都是 \(X\) 中用 \(Y/Z\) 二者其一换成了 \(S\),因此邻居数量仍然保持在 \(3w\) 内。