Back to all solutions
#1489 - Find Critical and Pseudo-Critical Edges in Minimum Spanning Tree
Problem Description
Given a weighted undirected connected graph with n vertices numbered from 0 to n - 1, and an array edges where edges[i] = [ai, bi, weighti] represents a bidirectional and weighted edge between nodes ai and bi. A minimum spanning tree (MST) is a subset of the graph's edges that connects all vertices without cycles and with the minimum possible total edge weight.
Find all the critical and pseudo-critical edges in the given graph's minimum spanning tree (MST). An MST edge whose deletion from the graph would cause the MST weight to increase is called a critical edge. On the other hand, a pseudo-critical edge is that which can appear in some MSTs but not all.
Note that you can return the indices of the edges in any order.
Solution
/**
* @param {number} n
* @param {number[][]} edges
* @return {number[][]}
*/
var findCriticalAndPseudoCriticalEdges = function(n, edges) {
const indexedEdges = edges.map((edge, i) => [...edge, i]);
indexedEdges.sort((a, b) => a[2] - b[2]);
const minWeight = getMSTWeight();
const critical = [];
const pseudoCritical = [];
for (let i = 0; i < edges.length; i++) {
if (getMSTWeight(i) > minWeight) {
critical.push(indexedEdges[i][3]);
} else if (getMSTWeight(-1, i) === minWeight) {
pseudoCritical.push(indexedEdges[i][3]);
}
}
return [critical, pseudoCritical];
function findParent(parents, x) {
if (parents[x] !== x) parents[x] = findParent(parents, parents[x]);
return parents[x];
}
function union(parents, ranks, x, y) {
const px = findParent(parents, x);
const py = findParent(parents, y);
if (px === py) return false;
if (ranks[px] < ranks[py]) {
parents[px] = py;
} else if (ranks[px] > ranks[py]) {
parents[py] = px;
} else {
parents[py] = px;
ranks[px]++;
}
return true;
}
function getMSTWeight(exclude = -1, include = -1) {
const parents = Array.from({ length: n }, (_, i) => i);
const ranks = new Array(n).fill(0);
let weight = 0;
let edgesUsed = 0;
if (include !== -1) {
const [u, v, w] = indexedEdges[include];
if (union(parents, ranks, u, v)) {
weight += w;
edgesUsed++;
}
}
for (let i = 0; i < indexedEdges.length; i++) {
if (i === exclude || i === include) continue;
const [u, v, w] = indexedEdges[i];
if (union(parents, ranks, u, v)) {
weight += w;
edgesUsed++;
}
}
return edgesUsed === n - 1 ? weight : Infinity;
}
};