Purpose: Maintain the connected components of an undirected graph under both edge insertions and deletions, in amortized per update and per connectivity query. Usually abbreviated HDT (2001).

The Difficulty

Insertions alone are easy β€” that is what DSU does in near-constant time. Deletions are the problem: removing a tree edge may or may not disconnect the graph, and finding a replacement edge requires searching the cut.

The Idea: edge levels

Assign every edge a level in , maintaining two invariants:

  1. Spanning forests are nested. = the spanning forest of edges at level ;
  2. Level- components are small. Every connected component of has at most vertices.

Invariant 2 is the whole engine: it caps the number of times an edge can be promoted at , which is where the amortization comes from.

Each forest is stored in an Euler tour tree so that link, cut, subtree size, and β€œfind any non-tree edge incident to this subtree” are all .

Operations

  • Insert : give it level 0. If are in different components of , add it to the forest; otherwise store it as a non-tree edge.
  • Delete : if it is a non-tree edge, just remove it. If it is a tree edge at level , remove it from every with and search for a replacement, from level downwards:
    • split the component into two parts; take the smaller one (guaranteed by invariant 2 to have vertices);
    • promote every level- tree edge in the smaller part to level β€” this is safe by invariant 2 and pays for itself;
    • scan the level- non-tree edges out of the smaller part. Each either connects to the other side (β†’ it is the replacement, done) or stays inside (β†’ promote it to level and continue).
  • Query : are they in the same tree of ?

Complexity

  • Update: amortized β€” each edge is promoted times, each promotion costing
  • Query: , or with a -tree-based Euler tour structure
  • Space:

The amortization argument

An edge’s level only ever increases, and it is bounded by . A scan that fails to find a replacement always promotes the edge it examined, so the cost of failed scans is charged to promotions. A scan that succeeds ends the operation. Total promotions over updates: , each . ∎

In a contest: use the offline version

If all queries are known in advance β€” which is nearly always the case in competitive programming β€” the segment tree on time approach is much simpler:

  1. Each edge exists during a time interval; insert it into nodes of a segment tree over the query timeline.
  2. DFS the segment tree, uniting edges on the way down and rolling back on the way up, with a rollback DSU (union by size, no path compression).
  3. Answer queries at the leaves.

, about 60 lines, and no Euler tour trees. See Dynamic Connectivity.

Variants / Use Cases

  • Dynamic MST β€” extend HDT with weights; amortized
  • Dynamic bipartiteness / 2-edge-connectivity β€” same level machinery with extra bookkeeping
  • Euler Tour Trees β€” the underlying structure
  • Link-Cut Trees β€” handle path aggregates, which Euler tour trees cannot
  • Frederickson β€” the earlier worst-case approach