forked from sleepybishop/nanorq
-
Notifications
You must be signed in to change notification settings - Fork 0
/
graph.c
59 lines (46 loc) · 1.58 KB
/
graph.c
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
#include "graph.h"
#define ASSIGN_PAIR(X, F, S) \
do { \
X.first = F; \
X.second = S; \
} while (0)
struct graph *graph_new(uint16_t size) {
struct graph *g = calloc(1, sizeof(struct graph));
kv_init(g->edges);
kv_resize(struct pair, g->edges, size);
for (uint16_t i = 0; i < size; i++) {
ASSIGN_PAIR(kv_A(g->edges, i), 1, i);
}
g->max_edges = 1;
return g;
}
uint16_t graph_find(struct graph *g, uint16_t id) {
uint16_t tmp = id;
while (kv_A(g->edges, tmp).second != tmp)
tmp = kv_A(g->edges, tmp).second;
return tmp;
}
void graph_link(struct graph *g, uint16_t node_a, uint16_t node_b) {
uint16_t rep_a = graph_find(g, node_a);
uint16_t rep_b = graph_find(g, node_b);
uint16_t s = kv_A(g->edges, rep_a).first + kv_A(g->edges, rep_b).first;
ASSIGN_PAIR(kv_A(g->edges, rep_a), s, rep_a);
ASSIGN_PAIR(kv_A(g->edges, rep_b), s, rep_a);
if (node_a != rep_a)
ASSIGN_PAIR(kv_A(g->edges, node_a), s, rep_a);
if (node_b != rep_b)
ASSIGN_PAIR(kv_A(g->edges, node_b), s, rep_a);
if (g->max_edges < kv_A(g->edges, rep_a).first) {
g->max_edges = kv_A(g->edges, rep_a).first;
}
}
bool graph_is_max(struct graph *g, uint16_t id) {
uint16_t e = graph_find(g, id);
return g->max_edges == kv_A(g->edges, e).first;
}
void graph_free(struct graph *g) {
if (g) {
kv_destroy(g->edges);
free(g);
}
}