动态图连通性笔记

首先离线的话有几种方法:

  • 线段树分治
  • 动态维护最大生成树:边的权值为他的(下一次)删除时间,加边正常做,询问时问路径最小值是否小于当前时刻.

动态图连通性 Holm-de Lichtenberg-Thorup (HLT)

  • 暴力:维护生成森林,若删树边则暴力找另一条边能替代这条树边.

  • 思想:给每条边赋一个“不重要度”. 每次未成功重连则提升之.

  • 算法:给每条边赋一个等级 \(\ell(e)\),初始为 0. 维护 \(\ell\) 意义下的最大生成森林:\(G_i=(V=V(G),E=\{e\in E(G)\mid\ell(e)\ge i\})\)(不需显式维护),\(F_i=G_i\cap F\),维护以下性质:

    1. \(F_i\)\(G_i\) 的生成森林 \(\Longleftrightarrow\) \(F_i\) 连通性与 \(G_i\) 相同 \(\Longleftrightarrow\) \(F_i\) 是以 \(\ell(e)\) 为边权的最大生成森林(树).(显然.)
    2. \(G_i\) 每个连通块大小 \(\le\left\lfloor\frac n{2^i}\right\rfloor\)(保证边权上界为 \(\lceil\log_2n\rceil\)).

    删一条树边 \(e=(v,w)\) 后我们寻找重连边 \(\text{reconnect}(e,\ell(e))\).

    性质 1 告诉我们重连边 \(e'\) 满足 \(\ell(e')\le\ell(e)\),不然原树不是最大的. 故从 \(\ell(e)\) 开始按 \(\ell\) 降序找:

    \(\text{reconnect}\left(e=(v,w),k\right)\)\(F_k\)\(e\) 把树分为 \(T_v,T_w\)(点集),不妨设 \(T_v\) 点数较小,把 \(T_v\) 上等级 \(=k\) 的边升到 \(k+1\). 【由于 \(T_v\) 点数较小,性质 2 仍满足(更具体地,\(T_v\) 点数 \(\le\left\lfloor\frac{连通块点数}2\right\rfloor\)),性质 1 显然满足.】然后找 \(T_v\) (图上)连出的等级 \(k\) 的边进行重连,若能则结束,否则升一级. 【此时这些边两侧都在 \(T_v\),而 \(T_v\)\(F_{k+1}\),显然不破坏性质 1.】若仍未成功,尝试 \(\text{reconnect}(e,k-1)\).

  • 时间:由性质 2,\(i>\lceil\log_2n\rceil\)\(G_i\) 就没点了,故 \(\ell(e)\le\lceil\log_2n\rceil\). 然后推理:

    1. 每条边只被上移 \(\log n\) 次.(显然)
    2. 总的来看,每条边只 \(\log n\) 次出现在 \(\text{reconnect}\).(因为每次失败都会上移.)
    3. 将一条边设为树边只需 \(O(\log n)\) 次树操作.(显然)
    4. 每次树操作可用 ETT, LCT, Top Tree, AAA 等之一完成,是 \(O(\log n)\).

    故修改 \(O(\log^2n)\),查询(\(\Leftrightarrow\)\(F_0\) 上查)是 \(O(\log n)\).

  • 实现细节:对每个 \(x,l\) 维护从 \(x\) 出发、等级 \(l\) 的非树边列表;在 \(F_k\) 上需枚举一些点(一个连通块 / 子树)中有哪些点有等级 \(k\) 的非树边,这个可对所有“有对应等级的点”在动态树上打标记,(显然复杂度对的).

代码咕.

posted @ 2024-07-15 11:24  Laijinyi  阅读(13)  评论(0编辑  收藏  举报