Introduction

Imagine you are maintaining a forest — a collection of trees — where edges appear and disappear over time. A road planner closes a highway and opens a bypass; a network engineer re-routes a cable; a compiler links and unlinks call-graph edges. At any moment you need to answer questions like: Are these two nodes connected? What is the maximum edge weight on the path between them?

The naive approach re-runs BFS or DFS after every change — O(n)O(n) per query in the worst case. For a forest that changes millions of times, that is catastrophic.

Link-cut trees, invented by Daniel Sleator and Robert Tarjan in 1983, do something remarkable: every link (add an edge), cut (remove an edge), and path query runs in O(logn)O(\log n) amortized time. The key idea is a clever decomposition of each tree into preferred paths — chains that absorb repeated access patterns — implemented with self-adjusting splay trees. Change the forest as often as you like; every operation stays logarithmic.

The result is the go-to tool for dynamic-graph problems, network flow algorithms, and competitive programming.

Try It: Live Forest

Below is a live forest of eight nodes. Click an edge button to toggle it: if the edge is absent it is linked (added); if it is present it is cut (removed). After each change the panel shows which nodes are connected and the path between any two highlighted nodes is listed.

Notice that checking connectivity after each link or cut feels instant — that is the O(logn)O(\log n) amortized guarantee at work. Try removing all edges from one node and watch it become its own isolated tree. Then reconnect it and see the component merge immediately.

The Real Complexity

How do link-cut trees achieve O(logn)O(\log n) amortized per operation? The answer lies in two interlocking ideas.

Preferred-path decomposition. Every node in the represented forest has at most one preferred child — whichever child was most recently accessed. The preferred children chain together into preferred paths, partitioning the forest into disjoint paths. When you access a node, you may change some preferred edges, but Sleator and Tarjan proved that the total number of preferred-edge changes across any sequence of mm operations is O(mlogn)O(m \log n).

Auxiliary splay trees. Each preferred path is stored in a splay tree keyed by depth. A splay tree is a self-adjusting BST that moves every accessed node to the root in O(logn)O(\log n) amortized time. Because the represented paths are short on average (by the preferred-path argument), the auxiliary trees stay balanced enough to keep every operation logarithmic.

The operations:

  • access(v) — makes vv the root of its auxiliary tree and splays all ancestors, re-routing preferred paths. This is the core primitive; everything else builds on it.
  • link(u, v) — connects two separate trees by making uu a child of vv; O(logn)O(\log n) amortized.
  • cut(v) — removes the edge from vv to its parent, splitting one tree into two; O(logn)O(\log n) amortized.
  • find-root(v) — returns the root of the tree containing vv; O(logn)O(\log n) amortized.
  • path-aggregate(u, v) — computes a fold (sum, max, min…) over all edges or nodes on the uuvv path; O(logn)O(\log n) amortized.

The amortized guarantee is proved with a potential function: Φ=vlog(size of subtree rooted at v)\Phi = \sum_v \log(\text{size of subtree rooted at } v). Each operation pays for itself plus a bounded decrease in potential, so the total cost over any sequence is O(mlogn)O(m \log n).

This was proven by Sleator and Tarjan in their 1983 paper "A Data Structure for Dynamic Trees" (STOC 1983, later in JCSS 1985). It remains the fastest known structure for this class of problems under the comparison model. See also dynamic shortest paths for a related application.

Where It Matters

Link-cut trees are not just a theoretical curiosity — they show up wherever a forest must evolve over time:

  • Network flow: Goldberg and Tarjan's push-relabel algorithm uses link-cut trees to find augmenting paths in O(nmlog(n2/m))O(nm \log(n^2/m)) time, shaving a log\log factor off earlier approaches. See max flow for the broader picture.
  • Dynamic connectivity: maintaining connected components in a graph under edge insertions uses link-cut trees as the inner forest structure.
  • Minimum spanning forest: adding or removing edges while keeping a spanning forest optimal (by weight) can be done in O(log2n)O(\log^2 n) per update using link-cut trees to manage the path-maximum queries.
  • Compiler and program analysis: call-graph transformations, dominator-tree updates, and control-flow refinements all modify tree structures at run time — link-cut trees make the bookkeeping efficient.
  • Competitive programming: link-cut trees appear in advanced ICPC and IOI problems whenever contestants must maintain dynamic trees with path aggregates.

Whenever you see "dynamic tree" or "online forest" in a problem statement, link-cut trees are almost certainly the right tool.

Conclusion

Link-cut trees solve a problem that looks simple but turns out to demand elegance: maintain a forest under arbitrary edge insertions and deletions while answering path queries in polylogarithmic time. Sleator and Tarjan's 1983 answer — decompose each tree into preferred paths, store each path in a splay tree, charge the amortized cost to potential — is a masterclass in how to tame dynamic data with a potential-function argument.

The next time you need to cut and re-link a network on the fly and still answer "are these nodes connected?" in milliseconds, you now know the structure that makes it possible. And if you enjoy how splay trees self-organize, explore dynamic shortest paths to see a closely related idea applied to weighted graphs.

Share this article

Pick a channel — or use your device's native share sheet.

Comments

Loading comments...

https://www.kipuhub.com/en/article/link-cut-trees/Content licensed under CC BY-NC 4.0.