File tree Expand file tree Collapse file tree 5 files changed +98
-11
lines changed Expand file tree Collapse file tree 5 files changed +98
-11
lines changed Original file line number Diff line number Diff line change
1
+ #ifndef CP_ALGO_DATA_STRUCTURES_DSU_HPP
2
+ #define CP_ALGO_DATA_STRUCTURES_DSU_HPP
3
+ #include < numeric>
4
+ #include < vector>
5
+ namespace cp_algo ::data_structures {
6
+ struct disjoint_set_union {
7
+ disjoint_set_union (int n): par(n) {
8
+ std::iota (begin (par), end (par), 0 );
9
+ }
10
+ int get (int v) {
11
+ return v == par[v] ? v : par[v] = get (par[v]);
12
+ }
13
+ bool uni (int a, int b) {
14
+ a = get (a);
15
+ b = get (b);
16
+ par[a] = b;
17
+ return a != b;
18
+ }
19
+ private:
20
+ std::vector<int > par;
21
+ };
22
+ using dsu = disjoint_set_union;
23
+ }
24
+ #endif // CP_ALGO_DATA_STRUCTURES_DSU_HPP
Original file line number Diff line number Diff line change @@ -35,13 +35,19 @@ namespace cp_algo::graph {
35
35
call_adjacent (v, callback, [](){return false ;});
36
36
}
37
37
void call_edges (auto &&callback) const {
38
- for (node_index v: nodes_view ()) {
39
- call_adjacent (v, [&](edge_index e) { callback (v, e);} );
38
+ for (edge_index e: edges_view ()) {
39
+ callback (e );
40
40
}
41
41
}
42
42
auto nodes_view () const {
43
43
return std::views::iota (0 , n ());
44
44
}
45
+ auto edges_view () const {
46
+ return std::views::filter (
47
+ std::views::iota (0 , 2 * m ()),
48
+ [](edge_index e) {return !(e % 2 );}
49
+ );
50
+ }
45
51
auto const & incidence_lists () const {return _adj;}
46
52
edge_t const & edge (edge_index e) const {return edges[e];}
47
53
node_index n () const {return _adj.size ();}
Original file line number Diff line number Diff line change @@ -10,15 +10,18 @@ namespace cp_algo::graph {
10
10
std::vector<int > deg (g.n ());
11
11
constexpr bool undirected = graph::undirected;
12
12
int res = 0 ;
13
- g.call_edges ([&](int u, int e) {
13
+ g.call_edges ([&](edge_index e) {
14
+ int u = g.edge (e ^ 1 ).to ;
15
+ int v = g.edge (e).to ;
14
16
res = u;
15
- if constexpr (undirected) {
16
- deg[u] ^= 1 ;
17
- } else {
18
- deg[u]++;
19
- deg[g.edge (e).to ]--;
20
- }
17
+ deg[u]++;
18
+ deg[v]--;
21
19
});
20
+ if constexpr (undirected) {
21
+ for (auto &it: deg) {
22
+ it = bool (it % 2 );
23
+ }
24
+ }
22
25
auto nodes = g.nodes_view ();
23
26
auto is_start = [&](int v) {return deg[v] > 0 ;};
24
27
auto starts = std::ranges::count_if (nodes, is_start);
@@ -42,8 +45,7 @@ namespace cp_algo::graph {
42
45
int e = adj.data [std::exchange (head[v], adj.next [head[v]])];
43
46
if (!used[e / 2 ]) {
44
47
used[e / 2 ] = 1 ;
45
- int u = g.edge (e).to ;
46
- self (self, u);
48
+ self (self, g.edge (e).to );
47
49
trail.push_back (e);
48
50
}
49
51
}
Original file line number Diff line number Diff line change
1
+ #ifndef CP_ALGO_GRAPH_MST_HPP
2
+ #define CP_ALGO_GRAPH_MST_HPP
3
+ #include " base.hpp"
4
+ #include " ../data_structures/dsu.hpp"
5
+ #include < algorithm>
6
+ namespace cp_algo ::graph {
7
+ template <weighted_edge_type edge_t >
8
+ auto mst (graph<undirected, edge_t > const & g) {
9
+ std::vector<std::pair<int64_t , edge_index>> edges;
10
+ g.call_edges ([&](edge_index e) {
11
+ edges.emplace_back (g.edge (e).w , e);
12
+ });
13
+ std::ranges::sort (edges);
14
+ data_structures::dsu me (g.n ());
15
+ int64_t total = 0 ;
16
+ std::vector<edge_index> mst;
17
+ for (auto [w, e]: edges) {
18
+ if (me.uni (g.edge (e ^ 1 ).to , g.edge (e).to )) {
19
+ total += w;
20
+ mst.push_back (e);
21
+ }
22
+ }
23
+ return std::pair{total, mst};
24
+ }
25
+ }
26
+ #endif // CP_ALGO_GRAPH_MST_HPP
Original file line number Diff line number Diff line change
1
+ // @brief Minimum Spanning Tree
2
+ #define PROBLEM " https://judge.yosupo.jp/problem/minimum_spanning_tree"
3
+ #pragma GCC optimize("Ofast,unroll-loops")
4
+ #include " cp-algo/graph/mst.hpp"
5
+ #include < bits/stdc++.h>
6
+
7
+ using namespace std ;
8
+ using namespace cp_algo ::graph;
9
+
10
+ void solve () {
11
+ int n, m;
12
+ cin >> n >> m;
13
+ graph<undirected, weighted_edge> g (n);
14
+ g.read_edges (m);
15
+ auto [X, E] = mst (g);
16
+ cout << X << " \n " ;
17
+ for (int e: E) {cout << e / 2 << " " ;}
18
+ }
19
+
20
+ signed main () {
21
+ // freopen("input.txt", "r", stdin);
22
+ ios::sync_with_stdio (0 );
23
+ cin.tie (0 );
24
+ int t = 1 ;
25
+ // cin >> t;
26
+ while (t--) {
27
+ solve ();
28
+ }
29
+ }
You can’t perform that action at this time.
0 commit comments