Skip to content

Commit 90208ae

Browse files
committed
Add Rectilinear minimum spanning tree
1 parent 85cb4a0 commit 90208ae

4 files changed

Lines changed: 60 additions & 0 deletions

File tree

‎code/geometry/rmst.cpp‎

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#define MAXN 100100
2+
struct RMST {
3+
struct point {
4+
int i; ll x, y;
5+
point() : i(-1) { }
6+
ll d1() { return x + y; }
7+
ll d2() { return x - y; }
8+
ll dist(point other) {
9+
return abs(x - other.x) + abs(y - other.y); }
10+
bool operator <(point other) {
11+
return y == other.y ? x > other.x : y < other.y; }
12+
} best[MAXN], arr[MAXN], tmp[MAXN];
13+
int n;
14+
RMST() : n(0) {}
15+
void add_point(int x, int y) {
16+
arr[arr[n].i = n].x = x, arr[n++].y = y; }
17+
void rec(int l, int r) {
18+
if (l >= r) return;
19+
int m = (l+r)/2;
20+
rec(l,m), rec(m+1,r);
21+
point bst;
22+
for (int i = l, j = m+1, k = l; i <= m || j <= r; k++) {
23+
if (j > r || (i <= m && arr[i].d1() < arr[j].d1())) {
24+
tmp[k] = arr[i++];
25+
if (bst.i != -1 && (best[tmp[k].i].i == -1
26+
|| best[tmp[k].i].d2() < bst.d2()))
27+
best[tmp[k].i] = bst;
28+
} else {
29+
tmp[k] = arr[j++];
30+
if (bst.i == -1 || bst.d2() < tmp[k].d2())
31+
bst = tmp[k]; } }
32+
rep(i,l,r+1) arr[i] = tmp[i]; }
33+
vector<pair<ll,ii> > candidates() {
34+
vector<pair<ll, ii> > es;
35+
rep(p,0,2) {
36+
rep(q,0,2) {
37+
sort(arr, arr+n);
38+
rep(i,0,n) best[i].i = -1;
39+
rec(0,n-1);
40+
rep(i,0,n) {
41+
if(best[arr[i].i].i != -1)
42+
es.push_back({arr[i].dist(best[arr[i].i]),
43+
{arr[i].i, best[arr[i].i].i}});
44+
swap(arr[i].x, arr[i].y);
45+
arr[i].x *= -1, arr[i].y *= -1; } }
46+
rep(i,0,n) arr[i].x *= -1; }
47+
return es; } };
48+
// vim: cc=60 ts=2 sts=2 sw=2:

‎code/geometry/rmst.test.cpp‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// Field testing: Kattis gridmst, CodeChef DRAGONST
2+
void test() {
3+
4+
}

‎comprog.pdf‎

1.72 KB
Binary file not shown.

‎comprog.tex‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,14 @@ \section{Geometry}
729729
\subsection{Rotating Calipers}
730730
\code{geometry/rotating_calipers.cpp}
731731

732+
\subsection{Rectilinear Minimum Spanning Tree}
733+
Given a set of $n$ points in the plane, and the aim is to find a
734+
minimum spanning tree connecting these $n$ points, assuming the
735+
Manhattan distance is used. The function \texttt{candidates} returns at
736+
most $4n$ edges that are a superset of the edges in a minimum spanning
737+
tree, and then one can use Kruskal's algorithm.
738+
\code{geometry/rmst.cpp}
739+
732740
\subsection{Line upper/lower envelope}
733741
To find the upper/lower envelope of a collection of lines $a_i+b_i x$,
734742
plot the points $(b_i,a_i)$, add the point $(0,\pm \infty)$ (depending

0 commit comments

Comments
 (0)