forked from righier/filter-kruskal
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfilterkruskal.hpp
50 lines (41 loc) · 1.24 KB
/
filterkruskal.hpp
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
#pragma once
#include <algorithm>
#include "kruskal.hpp"
#include "partition.hpp"
#include "pivot.hpp"
#include "unionfind.hpp"
#include "utils/graph.hpp"
static inline bool filter(DisjointSet &set, int a, int b) {
return set.compare(a, b);
}
static inline EdgeIt filterAll(DisjointSet &set, EdgeIt first, EdgeIt last) {
while (first < last) {
const Edge &e = *first;
if (filter(set, e.a, e.b)) {
*first = *(--last);
} else {
++first;
}
}
return last;
}
static inline void filterKruskal(DisjointSet &set, EdgeIt first, EdgeIt last,
int N, Edges &mst) {
u64 M = last - first;
if (M == 0) return;
if (M < 1000) return kruskal(set, first, last, N, true, mst);
EdgeIt pivotPos = pickRandomPivot(first, last);
EdgeIt mid = partition(first, last, pivotPos->w);
filterKruskal(set, first, mid, N, mst);
if (mst.size() < N - 1) addEdgeToMst(set, *pivotPos, mst);
if (mst.size() < N - 1) {
last = filterAll(set, mid, last);
filterKruskal(set, mid, last, N, mst);
}
}
static inline Edges filterKruskal(Edges &edges, int N) {
DisjointSet set(N);
Edges mst;
filterKruskal(set, edges.begin(), edges.end(), N, mst);
return mst;
}