-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathsolution.js
More file actions
80 lines (67 loc) · 1.89 KB
/
Copy pathsolution.js
File metadata and controls
80 lines (67 loc) · 1.89 KB
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
/**
* @param {number} V
* @param {number[][]} edges
* @return {number}
*/
class Solution {
secondMST(V, edges) {
const E = edges.length;
if (E === 0) return -1;
// Edge list
const arr = edges.map((e) => ({ u: e[0], v: e[1], w: e[2] }));
// DSU implementation
class DSU {
constructor(n) {
this.parent = Array(n);
this.rank = Array(n).fill(0);
for (let i = 0; i < n; i++) this.parent[i] = i;
}
find(x) {
if (this.parent[x] === x) return x;
this.parent[x] = this.find(this.parent[x]);
return this.parent[x];
}
unite(a, b) {
a = this.find(a);
b = this.find(b);
if (a === b) return false;
if (this.rank[a] < this.rank[b]) [a, b] = [b, a];
this.parent[b] = a;
if (this.rank[a] === this.rank[b]) this.rank[a]++;
return true;
}
}
// Sort by weight
arr.sort((a, b) => a.w - b.w);
// First MST
const dsu = new DSU(V);
let mstWeight = 0;
const mstIndices = [];
for (let i = 0; i < E; i++) {
if (dsu.unite(arr[i].u, arr[i].v)) {
mstWeight += arr[i].w;
mstIndices.push(i);
}
}
if (mstIndices.length !== V - 1) return -1;
let best = Number.MAX_SAFE_INTEGER;
// For each MST edge, ban it and rebuild MST
for (const banned of mstIndices) {
const d2 = new DSU(V);
let curWeight = 0;
let used = 0;
for (let i = 0; i < E; i++) {
if (i === banned) continue;
if (d2.unite(arr[i].u, arr[i].v)) {
curWeight += arr[i].w;
used++;
if (curWeight >= best) break;
}
}
if (used === V - 1 && curWeight > mstWeight) {
best = Math.min(best, curWeight);
}
}
return best === Number.MAX_SAFE_INTEGER ? -1 : best;
}
}