-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathemst.cc
65 lines (59 loc) · 1.32 KB
/
emst.cc
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
#include "emst.h"
struct edge {
double w;
int u, v;
friend bool operator<(const edge& a, const edge& b) {
if(std::abs(a.w - b.w) > EPS) {
return a.w > b.w;
}
return random() % 2;
}
edge(double d, int a, int b) {
w = d;
u = a;
v = b;
}
};
double distance(std::vector< int >& a, std::vector< int >& b) {
double ret = 0.0;
for(int i = 0; i < int(a.size()); ++i) {
double va = a[i], vb = b[i];
ret += (va - vb) * (va - vb);
}
return sqrt(ret);
}
int rep(std::vector< int >& v, int u) {
if(v[u] == u) {
return u;
}
return v[u] = rep(v, v[u]);
}
void join(std::vector< int >& v, int a, int b) {
v[rep(v, a)] = rep(v, b);
}
void compute_emst_subnet(net& v) {
int n = int(v.vertices.size());
std::priority_queue< edge > q;
for(int i = 0; i < n; ++i) {
for(int j = 0; j < i; ++j) {
q.push(edge(distance(v.vertices[i], v.vertices[j]), i, j));
}
}
std::vector< int > component(n);
for(int i = 0; i < n; ++i) {
component[i] = i;
}
while(!q.empty()) {
edge cur = q.top();
q.pop();
if(rep(component, cur.u) != rep(component, cur.v)) {
join(component, cur.u, cur.v);
v.subnets.push_back({cur.u, cur.v});
}
}
}
void compute_emst_subnets(instance& ins) {
for(auto& instance_net : ins.nets) {
compute_emst_subnet(instance_net);
}
}