AlgoMaster Logo

Maximize Spanning Tree Stability with Upgrades

hardFrequencyUpdated September 21, 2026

Understanding the Problem

We have a graph with n nodes and weighted edges. Some edges are mandatory (must = 1) and must appear in our spanning tree. The rest are optional (must = 0) and can be upgraded (doubling their strength) at most once each, with a budget of k total upgrades.

The stability of a spanning tree equals its weakest edge. We want to maximize that weakest edge.

Two facts shape the solution. First, must-edges are forced into the tree, cannot be upgraded, and cannot form a cycle. If they form a cycle, no valid spanning tree exists. Because they cannot be upgraded, the weakest must-edge is a hard ceiling on the answer.

Second, the problem asks us to maximize a minimum. That structure lets us replace the search for the best tree with a yes/no question: can we build a spanning tree where every edge has strength at least X? If we can answer that quickly, we binary search for the largest X.

Key Constraints:

  • n, edges.length <= 10^5 → An O(E log E) or O(E log(max_weight)) solution is required. Enumerating upgrade subsets is infeasible.
  • 1 <= s_i <= 10^5 → After one upgrade, the largest possible strength is 2 * 10^5 = 200,000. This caps the binary search range when no must-edge exists.
  • Must-edges cannot be upgraded → The weakest must-edge is a hard ceiling on stability, so the binary search never needs to look above it.

Approach 1: Brute Force (Try All Upgrade Combinations)

Intuition

Enumerate every subset of optional edges to upgrade (up to size k). For each subset, build the maximum spanning tree under those doubled weights and record its stability. The best stability across all subsets is the answer.

For one fixed subset, the maximum spanning tree maximizes the bottleneck edge: force-include all must-edges, sort the remaining optional edges by weight descending, and add them with Union-Find until the tree spans all nodes. Taking edges heaviest-first means the smallest edge we are forced to add is as large as possible, so the minimum edge in that tree is the best stability achievable for that weight assignment.

This is correct but exponential. With up to 10^5 optional edges, the number of subsets to try is C(E, k), far beyond what is feasible.

Algorithm

  1. Separate edges into must-edges and optional edges.
  2. Add all must-edges to Union-Find. If any creates a cycle, return -1.
  3. For each subset of optional edges of size 0 to k:
    • Double the weights of edges in the subset.
    • Sort optional edges by weight descending.
    • Greedily add optional edges to the spanning tree using Union-Find.
    • Track the minimum edge weight in the resulting tree.
  4. Return the maximum stability across all configurations.

Visualization and Code

Loading animation...

The next approach avoids enumerating upgrade combinations. Instead of asking which edges to upgrade, it fixes a target stability, then checks in one greedy pass whether that target is reachable, and binary searches for the largest target that is.

Approach 2: Binary Search + Greedy Union-Find

Intuition

Replace "what is the best stability?" with "is stability X achievable?" The second question has a fast yes/no answer, and the set of achievable X values is downward-closed, so binary search finds the largest X that works.

The approach runs in two phases.

Phase 1 (Preprocessing): Add all must-edges to Union-Find. If any closes a cycle, return -1. The minimum must-edge weight caps the answer, since must-edges cannot be upgraded, so it becomes the binary search upper bound.

Phase 2 (Binary Search): Sort optional edges by weight descending. For a candidate threshold mid, scan the optional edges and try to finish the spanning tree:

  • If an optional edge has weight w >= mid, add it without an upgrade.
  • If w < mid but 2 * w >= mid, add it and spend one upgrade (counting against k).
  • If 2 * w < mid, this edge cannot reach the threshold even doubled. Because the edges are sorted descending, no later edge can either, so stop scanning.

Processing edges heaviest-first keeps the upgrade budget for edges that need it. An edge already at or above mid is added without spending an upgrade, so upgrades go only to edges that fall short.

Algorithm

  1. Separate edges into must-edges and optional edges.
  2. Add all must-edges to a base Union-Find. If any creates a cycle, return -1. Track the minimum must-edge weight as the upper bound for binary search.
  3. Sort optional edges by weight in descending order.
  4. Binary search on the answer in range [0, mustMinWeight]:
    • For each threshold mid, clone the base Union-Find state.
    • Iterate through sorted optional edges: add free edges, then upgrade edges as needed (up to k), break when no edge can meet the threshold.
    • If the spanning tree completes (n - 1 edges selected), mid is feasible.
  5. Return the largest feasible value.

Visualization and Code

Loading animation...