1 条题解

  • 0
    @ 2025-8-24 22:47:58

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar ix35
    垒球

    搬运于2025-08-24 22:47:58,当前版本为作者最后更新于2023-06-03 23:33:47,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    白鹭兰

    我们首先考虑,如何判断是否有 k=1k=1,即是否存在一个点的排列,使得所有前缀和后缀的导出子图连通。将这个过程看成每次染黑一个点,时刻保证当前黑点和白点的导出子图都是连通的。

    考虑图的圆方树,如果所有点双连通分量没有构成一条链,就说明存在一个割点 xx 使得删去它后图分成至少三个连通块,设其中三个连通块为 C1,C2,C3C_1,C_2,C_3,由于加入 xx 前黑白点导出子图都是连通的,所以 C1,C2,C3C_1,C_2,C_3 至少有两个是纯白的(因为 xx 是白的),加入 xx 后这两个纯白的部分就一定不连通了,这说明一定不存在一个可行的方案。

    后面我们会构造证明,只要点双连通分量排成一条链,就一定有 k=1k=1 的解。

    下面考虑如何求最小的 kk,使得存在一种方案每次染黑至多 kk 个点,任何时刻黑白点导出子图都连通。我们设第一个被染黑的点(第一批 V1V_1 里任选一个)和最后一个(最后一批里任选一个)被染黑的点分别是 x,yx,y,不妨设它们都是圆方树的叶子(否则可以调整),考虑路径 xyx\to y

    对于 xyx\to y 上的某个圆点 zz,事实上根据前面的讨论,zz 连同其不在 xyx\to y 路径上的所有子树内的点都必须在同一次操作中被染黑,否则可以由和上面一样的方法导出矛盾。

    同理,对于 xyx\to y 上的某个方点 uu,对于其每一个不在 xyx\to y 路径上的儿子(圆点)vvvvxyx\to y 路径外侧的子树中的所有点必须在同一次操作中被染黑。

    这样我们得到了若干个必须同时被染黑的集合,称为关键集合,它们的大小的最大值就是这一组 (x,y)(x,y) 对应的 kk 的最小值。下图展示了一个例子,每个红框中的部分是每个关键集合:

    但是暴力枚举 x,yx,y 的复杂度太高,尝试分析一些性质。

    x,yx,y 的 LCA 是 zz,且分别属于 zz 的儿子 x0,y0x_0,y_0 的子树,x0x_0xx 的路径为 x0x1xs=xx_0\to x_1\to \ldots\to x_s=x,那么我们证明:存在一种最优的 xx,使得这个路径上任意两个相邻点都满足 xi+1x_{i+1}xix_i 的最大子树(i1i\ge 1)。

    这是因为,设 xix_i 的最大子树是 xx',其大小为 SS,如果 xi+1xx_{i+1}\ne x',则在 xix_i 处计算的贡献(xix_i 所在的关键集合大小)至少为 SS,然而如果将 xi+1x_{i+1} 调整为 xx',则在 xix_i 处计算的贡献一定会变小,而 xi+1x_{i+1} 子树内算的贡献一定不会超过 SS(因为整个子树大小只有 SS),因此一定不会更劣。

    于是我们可以用树形 DP 来计算答案。设 sn(x)sn(x) 表示 xx 的最大子树,记 f(x)f(x) 表示 xsn(x)sn2(x)x\to sn(x)\to sn^2(x)\to \ldots 这条路径上的贡献。对于某个点 zz,设其大小最大和次大的子树分别是儿子 x,yx,y 的子树,那么用 max(f(x),f(y),g(z,x,y))\max(f(x),f(y),g(z,x,y)) 更新答案即可,其中 g(z,x,y)g(z,x,y) 表示 zz 这里的贡献(同上不难证明选择最大和次大的子树 x,yx,y 是最优的)。

    上面我们已经解决了本题的第一部分,即圆方树上的部分,下一部分是构造答案,即一个点双连通分量内部怎么构造一种固定第一个染黑的点为 xx,最后一个染黑的点为 yy 的每次染黑一个点的方案。

    xx 为根,考虑 Tarjan 算法,对于每个点 uu 求出 DFS 树子树内通过返祖边可到达的最浅祖先 low(u)low(u)。考虑剥叶子,对于一个叶子 uu,它有两个邻居 f(u),low(u)f(u),low(u),我们可以在这两个点中的任意一个被染黑后立刻染黑 uu,染黑 uu 与否并不会对剩余部分的连通性产生影响,所以这一定是合法的。

    于是我们就从下往上考虑,对于每个点 xxvector 维护一个后继列表 LxL_x,每次删一个叶子 uu,就在 Lf(u)L_{f(u)}Llow(u)L_{low(u)} 中在末尾插入 uu。然后,我们染黑根结点 xx。每当染黑一个点 uu 时,就从前到后依次递归染黑 LuL_u 中的所有元素,这个过程中每个结点被染黑的顺序就是我们要求的答案。

    但是上面我们没有考虑到 yy 要最后一个染黑,为此我们对算法稍加修改:剥叶子剥到 yy 的时候就不剥了,这样 xyx\to y 路径上的点都会被保留,然后我们按照 xyx\to y 的顺序依次染黑这些点。我们断言染黑 yyLyL_y 中的点已经全是黑的了,从而 yy 就是最后一个被染黑的:这是因为如果染黑 yyLyL_y 中还有没被染黑的点,就说明有一个点的所有(yy 以下的)祖先和后代都没有连到 yy 的祖先的返祖边,这说明 yy 是一个割点。

    时间复杂度为 O(m)O(m)

    • 1

    信息

    ID
    8550
    时间
    1000ms
    内存
    512MiB
    难度
    7
    标签
    递交数
    0
    已通过
    0
    上传者