5
5
#include < ranges>
6
6
#include < vector>
7
7
namespace cp_algo ::graph {
8
+ using node_index = int ;
9
+ using edge_index = int ;
8
10
struct edge_base {
9
- int to;
11
+ node_index to;
10
12
11
13
edge_base () {}
12
- edge_base (int v): to(v) {}
14
+ edge_base (node_index v): to(v) {}
13
15
14
- static auto read (int v0 = 0 ) {
15
- int u, v;
16
+ static auto read (node_index v0 = 0 ) {
17
+ node_index u, v;
16
18
std::cin >> u >> v;
17
19
return std::pair{u - v0, edge_base (v - v0)};
18
20
}
@@ -21,54 +23,74 @@ namespace cp_algo::graph {
21
23
return {from};
22
24
}
23
25
};
24
- template <typename edge_info>
25
- concept edge_type = std::is_base_of_v<edge_base, edge_info>;
26
+
27
+ struct weighted_edge : edge_base {
28
+ int64_t w;
29
+
30
+ weighted_edge () {}
31
+ weighted_edge (node_index v, int64_t w): edge_base(v), w(w) {}
32
+
33
+ static auto read (node_index v0 = 0 ) {
34
+ node_index u, v;
35
+ int64_t w;
36
+ std::cin >> u >> v >> w;
37
+ return std::pair{u - v0, weighted_edge{v - v0, w}};
38
+ }
39
+
40
+ weighted_edge backedge (node_index from) const {
41
+ return {from, w};
42
+ }
43
+ };
44
+
45
+ template <typename edge>
46
+ concept edge_type = std::is_base_of_v<edge_base, edge>;
47
+ template <typename edge>
48
+ concept weighted_edge_type = std::is_base_of_v<weighted_edge, edge>;
26
49
27
50
enum type {directed = 0 , undirected = 1 };
28
- template <type _undirected, edge_type edge_info = edge_base>
51
+ template <type _undirected, edge_type edge_t = edge_base>
29
52
struct graph {
30
53
static constexpr bool undirected = _undirected;
31
- graph (int n, int v0 = 0 ): _n(n), _m( 0 ), v0(v0), _adj(n) {}
54
+ graph (int n, int v0 = 0 ): v0(v0), _adj(n) {}
32
55
33
- void add_edge (int u, edge_info e) {
34
- _m++;
56
+ void add_edge (node_index u, edge_t e) {
35
57
_adj.push (u, size (edges));
36
58
edges.push_back (e);
37
59
if constexpr (undirected) {
38
60
_adj.push (e.to , size (edges));
39
61
}
40
62
edges.push_back (e.backedge (u));
41
63
}
42
- void read_edges (int m) {
43
- for (int i = 0 ; i < m; i++) {
44
- auto [u, e] = edge_info ::read (v0);
64
+ void read_edges (node_index m) {
65
+ for (edge_index i = 0 ; i < m; i++) {
66
+ auto [u, e] = edge_t ::read (v0);
45
67
add_edge (u, e);
46
68
}
47
69
}
48
- void call_adjacent (int v, auto &&callback, auto &&terminate) const {
70
+ void call_adjacent (node_index v, auto &&callback, auto &&terminate) const {
49
71
for (int sv = _adj.head [v]; sv && !terminate (); sv = _adj.next [sv]) {
50
72
callback (_adj.data [sv]);
51
73
}
52
74
}
53
- void call_adjacent (int v, auto &&callback) const {
75
+ void call_adjacent (node_index v, auto &&callback) const {
54
76
call_adjacent (v, callback, [](){return false ;});
55
77
}
56
78
void call_edges (auto &&callback) const {
57
- for (int v: nodes_view ()) {
58
- call_adjacent (v, [&](int e) {callback (v, e);});
79
+ for (node_index v: nodes_view ()) {
80
+ call_adjacent (v, [&](edge_index e) {callback (v, e);});
59
81
}
60
82
}
61
83
auto nodes_view () const {
62
- return std::views::iota (0 , _n );
84
+ return std::views::iota (0 , n () );
63
85
}
64
86
auto const & incidence_lists () const {return _adj;}
65
- auto const & edge (int e) const {return edges[e];}
66
- int n () const {return _n ;}
67
- int m () const {return _m ;}
87
+ edge_t const & edge (edge_index e) const {return edges[e];}
88
+ size_t n () const {return _adj. size () ;}
89
+ size_t m () const {return size (edges) / 2 ;}
68
90
private:
69
- int _n, _m, v0;
70
- std::vector<edge_info > edges;
71
- data_structures::stack_union<int > _adj;
91
+ node_index v0;
92
+ std::vector<edge_t > edges;
93
+ data_structures::stack_union<edge_index > _adj;
72
94
};
73
95
}
74
96
#endif // CP_ALGO_GRAPH_BASE_HPP
0 commit comments