Kruskal Reconstruction Tree
Author: Ryan Fu
Decomposing Kruskal's algorithm to solve problems about minimum/maximum edge weights.
Tutorial
Suppose we want to support static path queries on a tree of size for the minimum edge between two vertices. Advanced readers may think of techniques like binary lifting, HLD, or even LCT to support operations in logarithmic complexity. A Kruskal Reconstruction Tree (KRT) can answer such queries in with construction.
We can build a KRT as follows:
- We start with components each representing each node
- Process each edge in sorted order. For an edge connecting , create an auxiliary node that is the parent of the topmost nodes in the components of and . Now, is the new topmost node in the merged component.
Note that maintaining the relationships of components can be done in amortized logarithmic complexity using path compression similar to a DSU.
We end up with a binary tree of size . We can support queries by returning the edge weight of the node corresponding to .
For a rough proof of correctness, consider the following:
Consider the KRT right before adding the node corresponding to . By definition of LCA, and are not connected, implying that the minimum weight edge can not be weighted less than . Additionally, because all edges added after the one corresponding to are of greater weight, our answer is indeed the edge corresponding to .
Thus, by using LCA methods, we can answer our queries with the aforementioned complexity.
Example - Qpwoeirut and Vertices
Focus Problem – try your best to solve this problem before continuing!
To solve this task, we can assign edge weights based on their index in the input order. Then, we can construct the Kruskal Tree, only processing edges between nodes that aren't already connected (similar to the Kruskal Tree's namesake, Kruskal's Algorithm).
From here, we need a fast way to query the of a range of nodes. One way to do this is to maintain the DFS order of the nodes, and take the of the nodes with the earliest and latest traversal within the range. This can be done with any range query data structure, such as a sparse table or segment tree.
Implementation
An optimal time complexity for this problem would be , using LCA and RMQ methods. However, we present an solution for simplicity.
#include <bits/stdc++.h>using namespace std;constexpr int MAX_N = 4e5 + 5;constexpr int LG = 20;int n, m, q, va[MAX_N], f[MAX_N], nx;int trace(int v) { return f[v] == v ? v : f[v] = trace(f[v]); }/** Implements LCA with binary lifting */
Problems
Status | Source | Problem Name | Difficulty | Tags | ||
---|---|---|---|---|---|---|
CC | Normal | Show TagsKRT | ||||
CF | Hard | Show TagsKRT | ||||
APIO | Hard | Show TagsKRT | ||||
CF | Hard | Show TagsKRT | ||||
IOI | Hard | Show TagsKRT |
Module Progress:
Join the USACO Forum!
Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!