-
Notifications
You must be signed in to change notification settings - Fork 25
/
Copy path1489-find-critical-and-pseudo-critical-edges-in-minimum-spanning-tree.js
87 lines (77 loc) · 2.67 KB
/
1489-find-critical-and-pseudo-critical-edges-in-minimum-spanning-tree.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/**
* 1489. Find Critical and Pseudo-Critical Edges in Minimum Spanning Tree
* https://leetcode.com/problems/find-critical-and-pseudo-critical-edges-in-minimum-spanning-tree/
* Difficulty: Hard
*
* 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.
*/
/**
* @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;
}
};