Shubham Sourabhthe room · director's cutplain résumé
Room 04 · The Grind — Advanced Graphs

Find Critical and Pseudo Critical Edges in Minimum Spanning Tree

HARD✓ CHIP-TIMEDLC #1489 — FULL STATEMENT

The briefingthe full drill, in my own words

The drill: A connected, weighted graph can have several different minimum spanning trees, all tied at the same total weight. Sort every edge into critical (in ALL of them), pseudo-critical (in SOME of them), or neither.

A connected, weighted graph arrives, and it can have more than one minimum spanning tree — different edge sets that all tie at the same lowest total weight.

Every edge in the graph gets sorted into one of three groups: critical, meaning it shows up in every minimum spanning tree without exception; pseudo-critical, meaning it shows up in at least one but not all of them; or neither, meaning no minimum spanning tree ever needs it.

The output lists the critical edges and the pseudo-critical edges separately, each identified by its position in the original edge list rather than by its endpoints.

  • graph stays connected and modest in size, up to roughly a hundred edges
  • edge weights are positive and can repeat across different edges
  • edges are identified by their index in the input list
  • output is two index lists: critical edges, then pseudo-critical edges
EX 01
n = 2 · edges = [[0, 1, 5]]
→ [[0], []]
single edge — trivially critical
EX 02
n = 3 · edges = [[0, 1, 1], [1, 2, 2], [0, 2, 3]]
→ [[0, 1], []]
triangle, distinct weights — the two cheap edges are both critical
EX 03
n = 3 · edges = [[0, 1, 1], [1, 2, 1], [0, 2, 1]]
→ [[], [0, 1, 2]]
triangle, tied weights — every edge is pseudo-critical

The hintstake only what you need

HINT 1 THE NUDGE

Every minimum spanning tree ties at the same total weight, even though the edge sets can differ. That single baseline weight is the yardstick both categories get measured against.

HINT 2 THE STRUCTURE

Test each edge two separate ways against that baseline: what happens to the achievable weight if this edge is banned outright, and separately, what's the best achievable weight if this edge is forced in before anything else runs?

HINT 3 ONE STEP FROM THE ANSWER

Ban edge i and rebuild the tree — a strictly higher weight (or a disconnected graph) makes it critical. Otherwise, force edge i in first and rebuild — landing back on the baseline weight makes it pseudo-critical.

Coach's boardthe pattern, step by step

TESTING EVERY WIREPATTERN · REBUILD PER EDGE, UNION-FINDtriangle: (0,1)=1 (1,2)=2 (0,2)=3
STEP 1

Triangle, 3 distinct weights: (0,1)=1, (1,2)=2, (0,2)=3. First find the baseline MST weight with Kruskal, then test each edge's necessity.

STEP 1 / 7 · ← → WORK TOO

The splitstwo paces, two languages

grind/find-critical-and-pseudo-critical-edges-in-minimum-spanning-tree.py — RACE PACE
LANG ▸
PACE ▸
class Solution:
    def findCriticalAndPseudoCriticalEdges(self, n: int, edges: List[List[int]]) -> List[List[int]]:
        base = self._weight(n, edges, -1, -1)
        critical, pseudo = [], []
        for i in range(len(edges)):
            if self._weight(n, edges, i, -1) > base:
                critical.append(i)
            elif self._weight(n, edges, -1, i) == base:
                pseudo.append(i)
        return [critical, pseudo]

    def _find(self, parent, x):
        while parent[x] != x:
            parent[x] = parent[parent[x]]
            x = parent[x]
        return x

    def _weight(self, n, edges, exclude, include):
        order = sorted(range(len(edges)), key=lambda i: edges[i][2])
        parent = list(range(n))
        total = 0
        count = 0
        if include != -1:
            u, v, w = edges[include]
            parent[self._find(parent, u)] = self._find(parent, v)
            total += w
            count += 1
        for idx in order:
            if idx == exclude or idx == include:
                continue
            if count == n - 1:
                break
            u, v, w = edges[idx]
            pu, pv = self._find(parent, u), self._find(parent, v)
            if pu != pv:
                parent[pu] = pv
                total += w
                count += 1
        return total if count == n - 1 else float('inf')
TIME O(E²·Α(V))SPACE O(E)PYTHON · RACE PACE · 39 LN

✓ CHIP-TIMEDALL 4 SOLUTIONS RAN GREEN AGAINST SELF-AUTHORED CASES IN CI · JDK 21 · CPYTHON 3.12 · NOTHING PUBLISHES RED