图的连通性与圆方树做题记录
CF51F. Caterpillar
因为题目中要求毛毛虫除自环外无环,因此对于原图的一个环,我们一定需要将它们缩成一个点,因此考虑对原图进行边双连通分量缩点,对于一个边双连通分量,将其缩为一个点的代价是 \(\text{siz}-1\),其中 \(\text{siz}\) 是当前边双连通分量的大小。
考虑处理缩完点后得到的树,由于毛毛虫满足存在一条链,使得其他点到这条链的距离 \(\le 1\),那么容易看出链上的所有点没有必要被删去,所有的叶子节点也没有必要被删去,也就是说,被合并掉的只有既不是链上的点,也不是叶子节点的点。考虑到叶子节点的个数是固定的,于是我们想要让链的长度最大,找直径即可。关注到直径和叶子节点有重复的部分,简单容斥即可。
对于连通块之间的贡献,可以考虑到只需要将两个连通块直径的端点合并,则新图一定符合要求。汇总上面的所有内容,答案即为
其中 \(\text{cnt}\) 是连通块个数,\(\text{dis}\) 是连通块缩点后的直径长度,\(\text{leaf}\) 是连通块缩点后的叶子节点个数,\(\{1/2\}\) 表示取值为 \(1\) 或 \(2\),更具体的,当连通块缩点后将仅剩一个点时,取值为 \(1\),否则为 \(2\)。可以在 \(O(n+m)\) 的复杂度内计算。
CF475E. Strongly Connected City 2
考虑到一个边双连通分量中定然存在一种定向方式,使得所有点互相可达,因此考虑边双连通分量缩点。对于缩点后的图,不难想到,可以选择一个点,使得其为根时,部分子树指向自己,自己指向剩下的子树,容易证明这种策略可以取到最优。考虑这样连边的贡献:每个点到自己子树内的任意一点都存在一条单向可达路径,两种不同的子树之间也存在一条单向路径。不难看出,当根固定时,前者的答案固定,因此仅需考虑后者,而后者的贡献显然是两种子树大小和的乘积,根据简单的不等式,我们看出两者越接近,乘积越大。因此,假设根节点的大小为 \(\text{siz}\),当一个子树大小和越接近 \(\lceil\frac{n-\text{siz}}{2}\rceil\) 时,答案越大。可以采用背包 dp 解决这个问题,复杂度是 \(O(n^2)\) 的。
CF855G. Harry Vs Voldemort
考虑到对于一个边双连通分量,在里面任意取三个点作为 \((u,v,w)\) 均可行,这启发我们对原图进行边双连通分量缩点,对于一个缩完点后的图,考虑统计它的贡献。不妨枚举每一个点作为 \(w\),那么对于一个大小为 \(\text{siz}\) 的边双连通分量,有 \(\text{siz}\) 种方法。接下来的 \(u,v\) 应该满足不在以 \(w\) 所在边双连通分量为根的同一子树内,这个可以简单容斥。综合分析,我们得到答案即为
其中 \(\text{siz}\) 为每个边双连通分量的大小,\(\text{son}\) 是与该边双连通分量相连的所有点,\(\text{sum}\) 是该边双连通分量为根的条件下,每个点的子树大小。这个式子可以简单树形 dp 做到 \(O(n)\) 统计,不用换根 dp,我们可以仅维护 \(1\) 为根意义下的答案,那么父亲的 \(\text{sum}\) 可以用 \(n-\text{sum}\) 表示。
现在考虑加边对答案产生的影响,不难看出,加边相当于将两个点之间的简单路径上的所有点缩为一个边双连通分量,于是原来这些点对答案的贡献消失,最后新产生的点会有新的贡献产生。这个过程中 \(\text{sum}\) 不变,因此其他点的贡献不变。对于新的点,\(\text{siz}\) 是所有点 \(\text{siz}\) 的简单相加,考虑如何快速维护 \(\sum\text{sum}(\text{sum}-1)\)。只需要对每一个点维护其儿子节点的 \(\text{sum}(\text{sum}-1)\) 的和,那么我们只需要将路径上的点维护的信息相加,减去路径上点的 \(\text{sum}(\text{sum}-1)\) ,就可以得到新点的儿子节点的和,然后新产生节点的贡献也可以按照上面的式子简单计算。合并的过程可以用并查集简单维护,单次操作需要枚举路径上的所有点,然后删除产生新的点,不难看出每个点只会被删除 \(1\) 次,每次只会产生 \(1\) 个点,那么复杂度是 \(O(n)\) 的。
BZOJ3331. [BeiJing2013] 压力
考虑到必须经过的点仅为起点、终点和随意一条路径上的割点,因此建立圆方树,然后简单树上差分即可得到正确答案,复杂度是 \(O(n\log n)\) 的。
CF1763F. Edge Queries
考虑到路径不能经过重复的点,因此我们需要对点双连通分量缩点,建立圆方树。考虑到对于一个点双连通分量,其中的所有边都存在一条路径使得其被经过,那么两个点之间任意一条路径上经过一个点双连通分量内的边都可以统计到答案中,于是一个方点的贡献就是其对应点双连通分量中的边数。特别的,因为没有重边,所以对于只有两个点的点双连通分量,这条边不能算入贡献。答案即为路径上的点的贡献和,用树上差分维护即可。
考虑怎么统计一个点双连通分量中有多少条边。根据题目给出的性质,我们可以简单想出一个点最多被包含在一个大小 \(>2\) 的点双连通分量中,那么只需要对每一个点打上标记,然后枚举每一条边就可以判断其在哪一个点双连通分量内。然而我们有更一般的做法:考虑每条边的两个端点在圆方树上一定存在相邻的方点,这个方点就是所求,于是我们可以先建出圆方树,通过树的结构判断哪一个方点是答案即可,更具体的,答案只可能是两者在树上的父亲方点。总复杂度是 \(O(n\log n)\)。
CF487E. Tourists
关注到不允许走重复点,考虑建立圆方树。并且观察发现一个点双连通分量内的所有点都一定存在一条路径经过,因此一个方点的贡献是其周围所有圆点的权值最小值,可以维护一个 muiltiset
。此时答案就是路径上点贡献的最小值,这个可以用树剖 + 线段树做到单次 \(O(\log^2 n)\)。然而我们发现修改时,需要对周围的所有方点做出修改,即删除原有权值后插入新权值,这样单次复杂度会退化至 \(O(n\log n)\),难以承受。
考虑路径上的圆点贡献在原先定义下是无用的,为了充分利用这个信息,我们可以将方点的权值改为其所有儿子圆点的权值最小值,这样修改时只用修改父亲方点的权值,复杂度下降至单次 \(O(\log n)\)。但此时维护的信息是错误的,因为 lca 处方点的父亲的贡献是没有统计的,但因为其他方点总伴随自己的父亲圆点出现,所以我们特判即可。总复杂度是 \(O(q\log^2 n)\) 的。
LG4630. [APIO2018] 铁人两项
阅读题面发现本题和【CF855G. Harry Vs Voldemort】较为相似,区别仅在于不允许经过相同的点,因此考虑在圆方树上 dp。和之前相同的思路,枚举每一个原点作为中转点,那么其他两个点不能出现在同一个圆点的子树内,用式子来讲就是
这里的定义和上文一样,注意因为图不一定连通,所以这里的 \(n\) 指的是连通块大小。对于后面的和式,我们以类似的思路,考虑维护每一个方点在以 \(1\) 为根的时候的所有儿子圆点的 \(\text{sum}(\text{sum}-1)\) 的和,父亲方点的儿子贡献只需要减掉自己,而父亲方点的父亲的子树的贡献可以通过 \(n-\text{sum}\) 直接得出,那么统计是没有困难的,复杂度为 \(O(n)\)。
LG4244. [SHOI2008] 仙人掌图
看到仙人掌考虑建立圆方树,因为每一个边双连通分量都是一个环,并且在圆方树的邻接表里每一个环都按顺序存储,因此两个点之间的最短路是容易计算的,我们考虑进行树形 dp。
- 对于一个圆点来说,我们可以选择它子树里的两条最长链从而得到一条可行链。
- 对于一个方点来说,我们可以选择两个儿子圆点合并成一条路径,或者选择一个儿子传递给父亲,问题在于如何找到最优的合并点。因为问题要求直径是两个点的最短路,所以如果点双连通分量的大小为 \(\text{siz}\),我们只能每个方向延展 \(\lfloor\frac{\text{siz}}{2}\rfloor\) 个点选择,假设两者的编号分别为 \(i,j\),则路径的长度为 \(f_{i,0}+f_{j,0}+|i-j|\),考虑按照两个方向枚举,这样可以去掉绝对值,然后是经典的单调队列优化,可以做到 \(O(n)\)。
LG6998. [NEERC 2013] Cactus Automorphisms
对仙人掌建立圆方树,考虑怎样的置换是可行的。考虑到能够进行交换的必要条件是两个子树大小一致,而重心以外的点均有一个子树大小 \(>\frac{n}{2}\),那么这个子树一定无法与其他子树交换,于是考虑以重心为根。注意到可能有两个重心,但这两个重心求出的结果相同,且互相不同构,因此可以忽略。
- 对于圆点来说,如果其子树存在有序同构,那么这些子树内的点可以随意乱换,因此贡献是所有等价类大小阶乘的乘积。
- 对于方点来说,如果其为重心,那么它既可以旋转,也可以翻折,因此我们考虑这个环的正串及反串的循环同构与原串相同的方法的个数;而如果不是重心,因为父亲子树是被固定的,所以其只能翻折,因此考虑这个环是否回文,如果回文有 \(2\) 的贡献。
关于树是否同构可以利用树哈希简单判断。然而注意方点判断匹配时要求子树是无序同构的,因此计算圆点的哈希值时各个子树应该是等价的。而圆点计算贡献时要求子树是有序同构的,也就是判断所有环的正序哈希和反序哈希是否存在相同,说明我们要按照顺序给不同的子树不同的哈希函数。
最后需要注意在方点时,如果该方点是仅包含两个圆点的点双连通分量,那么在旋转和翻折时会重复计算,需要特判。精细实现可以做到 \(O(n)\)。
LG5966. [POI 2016] Hydrorozgrywka
仙人掌肯定考虑圆方树,考虑继用普通树上的 dp 设计:令 \(f_i\) 表示从 \(i\) 点出发,不走出 \(i\) 点所在子树是否必胜。显然这个数组只对圆点有意义,因此转移是较为简单可以分类讨论出来的:
-
如果当前点的子树中存在可以到达的必胜点或可以逼迫对方走的必败点,那么这个点必胜。
可以到达的必胜点指的是在当前点子树内所有大小大于 \(2\) 的方点,在其原图对应环上两个方向上的第一个必胜点(没有则不考虑),且到当前点距离为偶数的点。因为我们选择这个方向走,沿途的点都是必败,所以不会提前走到其他的点,而走到这个点时先手可以走入这个必胜的子树,因此先手必胜。
可以逼迫对方走的必败点指的是在所有大小等于 \(2\) 的方点,沿着原图对应边到达的必败点。因为此时后手先走而必败,因此先手必胜。
-
否则如果当前点子树内的没有必胜点的方点的大小和为奇数,那么这个点必胜。
因为先手一定可以通过走奇环来切换先后手的顺序,而因为其他的方点没有使先手必胜的点,从而当后手先走时其必败,因此先手必胜。
我们可以在子树内方点统计有多少个必胜点到当前点的距离为偶数和没有必胜点的环的大小和,那么转移的总复杂度是 \(O(n)\) 的。
然而考虑到我们走完 \(i\) 所在子树后可以接着走子树外的环,那么这个做法是否有正确性?答案是有的。考虑如果存在一个圆点在不走出子树的情况下必胜,说明要么走到了一个非根的结点(这种情况正确性显然),要么说明回到根节点的最后一步是先手走的,进一步说明我们可以在这个点走入子树达到切换先后手顺序的目的,而后面面临的选择都是一样的,那么我们可以根据后面的必胜性决定当前的决策,不难看出我们总能找到必胜策略,因此认为这个点必胜是没有问题的。
这样可以求出以某一个点为起点时的必胜性,对于所有点的必胜性只需要进行换根 dp 即可做到 \(O(n)\)。
LG3180. [HAOI2016] 地图
对于仙人掌建立圆方树,断开中心点到当前点的所有路意味着只能走到子树内部,统计子树内部 \(\le y\) 且出现次数为奇数(或偶数)可以利用莫队 + 分块做到 \(O(n\sqrt{n})\),也可以利用线段树合并做到 \(O(n\log n)\)。
LG9194. [USACO23OPEN] Triples of Cows P
不难考虑在两个圆点之间加入一个方点,因为点 \(n\) 的最后删除的,因此不妨假设 \(n\) 为根,那么删除操作可以看作将所有儿子方点合并到当前点的父亲节点上。对于一个图,两个圆点是朋友当且仅当他们在树上有相邻的方点。
发现你要统计的三元组和【CF855G. Harry Vs Voldemort】【LG4630. [APIO2018] 铁人两项】长的比较像,考虑相似的思路:枚举每一个圆点作为 \(b\),那么 \(a,c\) 一定是 \(b\) 的朋友且互不相同,假设有 \(\text{cnt}\) 个数满足条件,那么贡献为 \(\text{cnt}(\text{cnt}-1)\)。然而考虑到在树的情境下这个内容较难求解,因此可以考虑将 \(\text{cnt}\) 拆成子树内的个数 \(s\) 和子树外的个数 \(t\),那么答案为 \((s+t)(s+t-1)=s^2+2st+t^2-s-t\)。\(s\) 是可以树形 dp 时简单求得的,通过观察可以发现 \(t\) 即为父亲方点的儿子个数,于是也可以简单求得。通过贡献延后计算我们可以得到答案即为
其中第一个求和要求是圆点,第二个符号要求是方点。对于后面的双重和式,是可以通过维护方点 \(\sum s\) 的值快速计算的,因此单次求解的复杂度是 \(O(n)\)。考虑删除一个点带来的影响,不难看出当前点、当前点的儿子和父亲、当前点父亲的父亲和当前点父亲的父亲的父亲会受到影响。
- 对于当前点,因为被删除了,所以贡献会消失,应当减去。
- 对于当前点的儿子,因为被合并了,所以贡献会消失,应当减去。
- 对于当前点的父亲,会删除一个儿子,然后加入很多个儿子,因此 \(t\) 和 \(\sum s\) 都会发生变化,可以减去原先贡献,最后加入新贡献。
- 对于当前点的父亲的父亲,因为儿子的 \(t\) 发生变化了,所以 \(s\) 也会发生变化,可以减去原先贡献,最后加入新贡献。
- 对于当前点的父亲的父亲,因为儿子的 \(s\) 发生变化了,所以 \(\sum s\) 也会发生变化,可以减去原先贡献,最后加入新贡献。
可以利用并查集维护每个点的父亲合到了哪一个点上,这些操作可以在均摊 \(O(1)\) 的时间内完成,因此总复杂度是 \(O(n)\) 的。
LG9167. [省选联考 2023] 城市建造
考虑到如果选择一个点双中的点超过两个,那么如果不选择整个点双,一定不可能使城市之间不连通,因此考虑构建圆方树。称选择一个方点表示选择其对应点双中的所有圆点。如果我们选择了两个方点,不难看出,其在树上的简单路径上的所有方点也一定要选择。通过观察发现,如果以重心为根,那么选择一个方点意味着其父亲方点也要选择,证明考虑非重心方点的父亲子树大小一定 \(>\frac{n}{2}\),如果不选择其他方点,那么这种划分不合理,否则选择的路径一定使得父亲方点被选。这里的重心是在不计方点的前提下统计的。可以考虑对 \(k\) 的取值分开进行 dp,下文对于圆点,\(f_u\) 表示选择 \(u\) 点父亲的合法方案数;对于方点表示选择 \(u\) 点的方案数。
-
\(k=0\)
这种情况下所有连通块的大小一定是一样的,且为 \(n\) 的因数,可以考虑枚举。对于每一个因数 \(d\),考虑当前子树如果大小 \(\ge d\),那么子树内一定有点被选择,根据上面的结论,这个点一定会被选择,否则一定不合法,于是如果此时 \(f_u=0\),说明当前情况不合法。
- 对于圆点,考虑所有大小没有达到 \(d\) 的子树,一定需要和自己合并,否则应当会被选择单独,不会和自己合并。这样可以算出来自己所在的块的最终大小,如果不为 \(d\) 则选择不合法。
- 对于方点,如果儿子中有不能选择的点,那么一定无法成功选择当前方点。
单次复杂度是 \(O(n)\) 的,总复杂度可以做到 \(O(nd(n))\)
-
\(k=1\)
这种情况下所有连通块的大小应该在 \([d,d+1]\) 之间,可以看出 \(d\) 一定为某个 \(\lfloor\frac{n}{i}\rfloor\) 的值,因此可以用整数分块枚举。考虑一个子树大小 \(\ge d\) 的点:
- 对于圆点,考虑所有大小没有达到 \(d\) 的子树,这些子树一定需要和自己合并。而大小 \(=d\) 的子树,可以合并也可以不合并,但合并时要求当前点没有必须合并的子树,否则当前点所在连通块的大小一定不符合条件。大小 \(>d\) 的子树一定需要选择。考虑求出所有必须合并的子树的大小和 \(\text{sum}\),大小 \(=d\) 且可以合并的子树个数 \(\text{cnt}\),和所有大小 \(>d\) 的子树的方案总数 \(\text{prd}=\prod f_v\)。继续分类讨论:
- \(\text{sum}=d\lor \text{sum}=d+1\),说明此时什么都不动就可以,那么方案总数应该加上 \(\text{prd}\)。
- \(\text{sum}=1\),说明此时可以选择任意一个 \(=d\) 且可以合并的子树,加上其他子树选择的方案数,总数应该加上 \(\text{cnt}\times\text{prd}\)。
- 对于方点,不难看出子树圆点都必须选择,那么方案数为 \(\prod f_v\)。
考虑一个大小 \(>d\) 且 \(f_u=0\) 的点,不难看出这个点所在连通块一定不合法,那么当前情况不合法。考虑到这样子我们可能会让所有连通块选择 \(d+1\),那么需要单独减去这部分的贡献。因为最多有 \(O(\sqrt n)\) 种可行的 \(d\),这个部分的复杂度是 \(O(n\sqrt n)\) 的。
- 对于圆点,考虑所有大小没有达到 \(d\) 的子树,这些子树一定需要和自己合并。而大小 \(=d\) 的子树,可以合并也可以不合并,但合并时要求当前点没有必须合并的子树,否则当前点所在连通块的大小一定不符合条件。大小 \(>d\) 的子树一定需要选择。考虑求出所有必须合并的子树的大小和 \(\text{sum}\),大小 \(=d\) 且可以合并的子树个数 \(\text{cnt}\),和所有大小 \(>d\) 的子树的方案总数 \(\text{prd}=\prod f_v\)。继续分类讨论: