ac-library-rb 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.github/workflows/unittest.yml +16 -0
- data/.gitignore +11 -0
- data/.rubocop.yml +198 -0
- data/Gemfile +3 -0
- data/LICENSE +116 -0
- data/README.ja.md +56 -0
- data/README.md +41 -0
- data/Rakefile +11 -0
- data/ac-library-rb.gemspec +32 -0
- data/bin/console +8 -0
- data/bin/lock_lib.rb +27 -0
- data/bin/setup +8 -0
- data/document_en/binary_index_tree.md +3 -0
- data/document_en/convolution.md +67 -0
- data/document_en/dsu.md +132 -0
- data/document_en/fenwick_tree.md +99 -0
- data/document_en/index.md +79 -0
- data/document_en/lazy_segtree.md +141 -0
- data/document_en/math.md +104 -0
- data/document_en/max_flow.md +165 -0
- data/document_en/min_cost_flow.md +132 -0
- data/document_en/modint.md +263 -0
- data/document_en/priority_queue.md +119 -0
- data/document_en/segtree.md +134 -0
- data/document_en/string.md +106 -0
- data/document_en/two_sat.md +91 -0
- data/document_en/union_find.md +3 -0
- data/document_ja/convolution.md +64 -0
- data/document_ja/dsu.md +183 -0
- data/document_ja/fenwick_tree.md +83 -0
- data/document_ja/index.md +89 -0
- data/document_ja/lazy_segtree.md +135 -0
- data/document_ja/math.md +116 -0
- data/document_ja/max_flow.md +129 -0
- data/document_ja/min_cost_flow.md +105 -0
- data/document_ja/modint.md +349 -0
- data/document_ja/priority_queue.md +103 -0
- data/document_ja/scc.md +65 -0
- data/document_ja/segtree.md +145 -0
- data/document_ja/string.md +105 -0
- data/document_ja/two_sat.md +87 -0
- data/lib/ac-library-rb/version.rb +3 -0
- data/lib/convolution.rb +124 -0
- data/lib/core_ext/modint.rb +19 -0
- data/lib/crt.rb +52 -0
- data/lib/dsu.rb +44 -0
- data/lib/fenwick_tree.rb +48 -0
- data/lib/floor_sum.rb +21 -0
- data/lib/inv_mod.rb +26 -0
- data/lib/lazy_segtree.rb +149 -0
- data/lib/lcp_array.rb +23 -0
- data/lib/max_flow.rb +137 -0
- data/lib/min_cost_flow.rb +143 -0
- data/lib/modint.rb +170 -0
- data/lib/pow_mod.rb +13 -0
- data/lib/priority_queue.rb +89 -0
- data/lib/scc.rb +77 -0
- data/lib/segtree.rb +140 -0
- data/lib/suffix_array.rb +128 -0
- data/lib/two_sat.rb +34 -0
- data/lib/z_algorithm.rb +32 -0
- data/lib_helpers/ac-library-rb/all.rb +22 -0
- data/lib_lock/ac-library-rb.rb +22 -0
- data/lib_lock/ac-library-rb/convolution.rb +126 -0
- data/lib_lock/ac-library-rb/core_ext/modint.rb +19 -0
- data/lib_lock/ac-library-rb/crt.rb +54 -0
- data/lib_lock/ac-library-rb/dsu.rb +46 -0
- data/lib_lock/ac-library-rb/fenwick_tree.rb +50 -0
- data/lib_lock/ac-library-rb/floor_sum.rb +23 -0
- data/lib_lock/ac-library-rb/inv_mod.rb +28 -0
- data/lib_lock/ac-library-rb/lazy_segtree.rb +151 -0
- data/lib_lock/ac-library-rb/lcp_array.rb +25 -0
- data/lib_lock/ac-library-rb/max_flow.rb +139 -0
- data/lib_lock/ac-library-rb/min_cost_flow.rb +145 -0
- data/lib_lock/ac-library-rb/modint.rb +172 -0
- data/lib_lock/ac-library-rb/pow_mod.rb +15 -0
- data/lib_lock/ac-library-rb/priority_queue.rb +91 -0
- data/lib_lock/ac-library-rb/scc.rb +79 -0
- data/lib_lock/ac-library-rb/segtree.rb +142 -0
- data/lib_lock/ac-library-rb/suffix_array.rb +130 -0
- data/lib_lock/ac-library-rb/two_sat.rb +36 -0
- data/lib_lock/ac-library-rb/z_algorithm.rb +34 -0
- metadata +158 -0
@@ -0,0 +1,141 @@
|
|
1
|
+
# LazySegtree
|
2
|
+
|
3
|
+
This is a lazy evaluation segment tree.
|
4
|
+
|
5
|
+
## Class Methods.
|
6
|
+
|
7
|
+
### new(v, e, id, op, mapping, composition)
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
seg = LazySegtree.new(v, e, id, op, mapping, compositon)
|
11
|
+
```
|
12
|
+
|
13
|
+
The first argument can be an `Integer` or an `Array`.
|
14
|
+
|
15
|
+
- If the first argument is an `Integer` of `n`, a segment tree of length `n` and initial value `e` will be created.
|
16
|
+
- If the first argument is `a` of `Array` with length `n`, a segment tree will be created based on `a`.
|
17
|
+
|
18
|
+
The second argument `e` is the unit source. We need to define the monoid by defining the binary operation `op(x, y)` in the block.
|
19
|
+
|
20
|
+
**Complexity**
|
21
|
+
|
22
|
+
- `O(n)`
|
23
|
+
|
24
|
+
## Instance methods.
|
25
|
+
|
26
|
+
## set(pos, x)
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
seg.set(pos, x)
|
30
|
+
```
|
31
|
+
|
32
|
+
Assign `x` to `a[pos]`.
|
33
|
+
|
34
|
+
**Complexity**
|
35
|
+
|
36
|
+
- `O(logn)`
|
37
|
+
|
38
|
+
### get(pos) -> same class as unit source e
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
seg.get(pos)
|
42
|
+
```
|
43
|
+
|
44
|
+
It returns `a[pos]`.
|
45
|
+
|
46
|
+
**Complexity**
|
47
|
+
|
48
|
+
- `O(1)`
|
49
|
+
|
50
|
+
### prod(l, r) -> same class as unit source e
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
seg.prod(l, r)
|
54
|
+
```
|
55
|
+
|
56
|
+
It returns `op(a[l], ... , a[r - 1])`.
|
57
|
+
|
58
|
+
**Constraints**
|
59
|
+
|
60
|
+
- `0 ≤ l ≤ r ≤ n`.
|
61
|
+
|
62
|
+
**Complexity**
|
63
|
+
|
64
|
+
- `O(logn)`
|
65
|
+
|
66
|
+
### all_prod -> same class as unit source e
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
seg.all_prod
|
70
|
+
```
|
71
|
+
|
72
|
+
It returns `op(a[0], ... , a[n - 1])`.
|
73
|
+
|
74
|
+
**Complexity**
|
75
|
+
|
76
|
+
- `O(1)`.
|
77
|
+
|
78
|
+
### apply(pos, val)
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
seg.apply(pos, val)
|
82
|
+
```
|
83
|
+
|
84
|
+
The implementation with three arguments in the original code is called `range_apply` in this library. If it looks OK after measuring the execution time, we can make the `apply` method support both 2 and 3 arguments.
|
85
|
+
|
86
|
+
**Constraints**
|
87
|
+
|
88
|
+
- `0 ≤ pos < n`.
|
89
|
+
|
90
|
+
**Complexity**
|
91
|
+
|
92
|
+
- `O(log n)`.
|
93
|
+
|
94
|
+
### range_apply(l, r, val)
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
seg.range_apply(l, r, val)
|
98
|
+
```
|
99
|
+
|
100
|
+
**Constraints**
|
101
|
+
|
102
|
+
- `0 ≤ l ≤ r ≤ n`.
|
103
|
+
|
104
|
+
**Complexity**
|
105
|
+
|
106
|
+
- `O(log n)`
|
107
|
+
|
108
|
+
### max_right.
|
109
|
+
|
110
|
+
[TODO] Someone with some free time will write.
|
111
|
+
|
112
|
+
### min_left
|
113
|
+
|
114
|
+
[TODO] The code side is not implemented yet.
|
115
|
+
|
116
|
+
## Verified
|
117
|
+
|
118
|
+
This is the link in question. There is no code, but it has been Verified.
|
119
|
+
- [AIZU ONLINE JUDGE DSL\_2\_F RMQ and RUQ](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_F)
|
120
|
+
- [AIZU ONLINE JUDGE DSL\_2\_G RSQ and RAQ](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_G)
|
121
|
+
|
122
|
+
The following problem is not AC in Ruby because the execution time is strictly TLE.
|
123
|
+
- [ALPC: K \- Range Affine Range Sum](https://atcoder.jp/contests/practice2/tasks/practice2_k)
|
124
|
+
- [ALPC: L \- Lazy Segment Tree](https://atcoder.jp/contests/practice2/tasks/practice2_l)
|
125
|
+
|
126
|
+
## Reference links
|
127
|
+
|
128
|
+
- ac-library-rb
|
129
|
+
- [Code: lazy_segtree.rb](https://github.com/universato/ac-library-rb/blob/master/lib/lazy_segtree.rb)
|
130
|
+
- [Test code: lazy_segtree_test.rb](https://github.com/universato/ac-library-rb/blob/master/test/lazy_segtree_test.rb)
|
131
|
+
- AtCoder Library
|
132
|
+
- [Document: lazysegtree.md(GitHub)](https://github.com/atcoder/ac-library/blob/master/document_en/lazysegtree.md)
|
133
|
+
- [Documentat: appendix.md(GitHub)](https://github.com/atcoder/ac-library/blob/master/document_en/appendix.md)
|
134
|
+
- [Code: lazysegtree.hpp(GitHub)](https://github.com/atcoder/ac-library/blob/master/atcoder/lazysegtree.hpp)
|
135
|
+
- [Test code: lazysegtree_test.cpp(GitHub)](https://github.com/atcoder/ac-library/blob/master/test/unittest/lazysegtree_test.cpp )
|
136
|
+
|
137
|
+
## Differences from the original library.
|
138
|
+
|
139
|
+
### Not `ceil_pow2`, but `bit_length`.
|
140
|
+
|
141
|
+
The original C++ library uses the original `internal::ceil_pow2` function, but this library uses the existing Ruby method `Integer#bit_length`. This library uses the existing Ruby method `Integer#bit_length`, which is faster than the original method.
|
data/document_en/math.md
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
# Math
|
2
|
+
|
3
|
+
It contains number-theoretic algorithms.
|
4
|
+
|
5
|
+
- `pow_mod`
|
6
|
+
- `inv_mod`
|
7
|
+
- `crt`
|
8
|
+
- `floor_sum`
|
9
|
+
|
10
|
+
## pow_mod
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
pow_mod(x, n, m)
|
14
|
+
```
|
15
|
+
|
16
|
+
It returns `(x**n) % m`.
|
17
|
+
|
18
|
+
However, Ruby core has `Integer#pow`. Use it.
|
19
|
+
|
20
|
+
**Constraints**
|
21
|
+
|
22
|
+
- `n`, `m` are intergers.
|
23
|
+
- `0 ≦ n`, `1 ≦ m`
|
24
|
+
|
25
|
+
**Complexity**
|
26
|
+
|
27
|
+
- `O(log n)`
|
28
|
+
|
29
|
+
## inv_mod
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
inv_mod(x, n, m)
|
33
|
+
```
|
34
|
+
|
35
|
+
It returns an integer `y` such that `0 ≦ y < m` and `xy ≡ 1 (mod m)`.
|
36
|
+
|
37
|
+
If m is a prime number, Use `x.pow(m - 2, m)`。
|
38
|
+
|
39
|
+
**Constraints**
|
40
|
+
|
41
|
+
- `gcd(x, m) = 1`, `1 ≦ m`
|
42
|
+
|
43
|
+
**Complexity**
|
44
|
+
|
45
|
+
- `O(log m)`
|
46
|
+
|
47
|
+
### Verified
|
48
|
+
- [ABC186 E - Throne](https://atcoder.jp/contests/abc186/tasks/abc186_e)
|
49
|
+
- [AC Code(59ms) 2020/12/20](https://atcoder.jp/contests/abc186/submissions/18898186)
|
50
|
+
|
51
|
+
## crt(r, m) -> [rem , mod] or [0, 0]
|
52
|
+
|
53
|
+
Chinese remainder theorem
|
54
|
+
|
55
|
+
|
56
|
+
Given two arrays `r`, `m` with length `n`, it solves the modular equation system
|
57
|
+
|
58
|
+
`x ≡ r[i] (mod m[i]), ∀i ∈ {0, 1, …… n - 1}`
|
59
|
+
|
60
|
+
If there is no solution, it returns `[0, 0]`.
|
61
|
+
|
62
|
+
If there is a solution, all the solutions can be written as the form `x ≡ rem(mod)`. it returns `[rem ,mod]`
|
63
|
+
|
64
|
+
|
65
|
+
## Verified
|
66
|
+
|
67
|
+
Problems
|
68
|
+
- [No\.187 中華風 \(Hard\) \- yukicoder](https://yukicoder.me/problems/no/187)
|
69
|
+
|
70
|
+
## floor_sum(n, m, a, b)
|
71
|
+
|
72
|
+
$\sum_{i = 0}^{n - 1} \mathrm{floor}(\frac{a \times i + b}{m})$
|
73
|
+
|
74
|
+
It retrurns `Σ[k = 0 → n - 1] floor((a * i + b) / m)`
|
75
|
+
|
76
|
+
**Complexity**
|
77
|
+
|
78
|
+
- `O(log(n + m + a + b))`
|
79
|
+
|
80
|
+
## Verified
|
81
|
+
|
82
|
+
[ALPC: C \- Floor Sum](https://atcoder.jp/contests/practice2/tasks/practice2_c)
|
83
|
+
- [AC Code 426ms 2020/9/14](https://atcoder.jp/contests/practice2/submissions/16735215)
|
84
|
+
|
85
|
+
## 参考リンク
|
86
|
+
|
87
|
+
- ac-library-rb
|
88
|
+
- codes in ac-library-rb
|
89
|
+
- [Code pow_mod.rb](https://github.com/universato/ac-library-rb/blob/master/lib/pow_mod.rb)
|
90
|
+
- [Code inv_mod.rb](https://github.com/universato/ac-library-rb/blob/master/lib/inv_mod.rb)
|
91
|
+
- [Code crt.rb](https://github.com/universato/ac-library-rb/blob/master/lib/crt.rb)
|
92
|
+
- [Code floor_sum.rb](https://github.com/universato/ac-library-rb/blob/master/lib/floor_sum.rb)
|
93
|
+
- test in ac-library-rb
|
94
|
+
- [Test pow_mod_test.rb](https://github.com/universato/ac-library-rb/blob/master/test/pow_mod.rb)
|
95
|
+
- [Test inv_mod_test.rb](https://github.com/universato/ac-library-rb/blob/master/test/inv_mod.rb)
|
96
|
+
- [Test crt_test.rb](https://github.com/universato/ac-library-rb/blob/master/test/crt.rb)
|
97
|
+
- [Test floor_sum_test.rb](https://github.com/universato/ac-library-rb/test/master/lib/floor_sum.rb)
|
98
|
+
- AtCoder Library
|
99
|
+
- [Code math.hpp](https://github.com/atcoder/ac-library/blob/master/atcoder/math.hpp)
|
100
|
+
- [Code internal_math.hpp](https://github.com/atcoder/ac-library/blob/master/atcoder/internal_math.hpp)
|
101
|
+
- [Test math_test.cpp](https://github.com/atcoder/ac-library/blob/master/test/unittest/math_test.cpp)
|
102
|
+
- [Document math.md](https://github.com/atcoder/ac-library/blob/master/document_ja/math.md)
|
103
|
+
- [Document math.html](https://atcoder.github.io/ac-library/document_en/math.html)
|
104
|
+
- [Relax the constraints of floor\_sum? · Issue \#33 · atcoder/ac\-library](https://github.com/atcoder/ac-library/issues/33)
|
@@ -0,0 +1,165 @@
|
|
1
|
+
# MaxFlow
|
2
|
+
|
3
|
+
Library for solving [Maximum flow problem](https://en.wikipedia.org/wiki/Maximum_flow_problem).
|
4
|
+
|
5
|
+
|
6
|
+
## Class Methods.
|
7
|
+
|
8
|
+
### new(n = 0) -> MaxFlow
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
graph = Maxflow.new(10)
|
12
|
+
```
|
13
|
+
|
14
|
+
It creates a graph of `n` vertices and `0` edges.
|
15
|
+
|
16
|
+
**Complexity**
|
17
|
+
|
18
|
+
- `O(n)`
|
19
|
+
|
20
|
+
## Instance Methods.
|
21
|
+
|
22
|
+
### add_edge(from, to, cap) -> Integer
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
graph.add_edge(0, 1, 5)
|
26
|
+
```
|
27
|
+
|
28
|
+
It adds an edge oriented from the vertex `from` to the vertex `to` with the capacity cap and the flow amount `0`.
|
29
|
+
|
30
|
+
It returns an integer `k` such that this is the `k`-th edge that is added.
|
31
|
+
|
32
|
+
**Complexity**
|
33
|
+
|
34
|
+
- `O(1)` amortized
|
35
|
+
|
36
|
+
|
37
|
+
|
38
|
+
|
39
|
+
### flow(start, to, flow_limit = 1 << 64) -> Integer
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
(1) graph.flow(0, 3)
|
43
|
+
(2) graph.flow(0, 3, flow_limit)
|
44
|
+
```
|
45
|
+
|
46
|
+
- It augments the flow from `s` to `t` as much as possible. It returns the amount of the flow augmented.
|
47
|
+
|
48
|
+
**Aliases**
|
49
|
+
|
50
|
+
- `max_flow`
|
51
|
+
- `flow`
|
52
|
+
|
53
|
+
**Constraints**
|
54
|
+
|
55
|
+
- `start ≠ to`
|
56
|
+
|
57
|
+
### min_cut(start) -> Array(boolean)
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
graph.min_cut(start)
|
61
|
+
```
|
62
|
+
|
63
|
+
The return value is an array of length `n`.
|
64
|
+
|
65
|
+
The `i`-th element of the return value is filled with `true` if the vertex `start` to `i` is reachable by the remainder graph, otherwise it is filled with `false`.
|
66
|
+
|
67
|
+
**Complexity**
|
68
|
+
|
69
|
+
- `O(n + m)`, where `m` is the number of added edges.
|
70
|
+
|
71
|
+
### get_edge(i) -> [from, to, cap, flow].
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
graph.get_edge(i)
|
75
|
+
graph.edge(i)
|
76
|
+
graph[i].
|
77
|
+
```
|
78
|
+
|
79
|
+
- It returns the current internal state of the `i`-th edge.
|
80
|
+
- The edges are ordered in the same order as added by `add_edge`.
|
81
|
+
|
82
|
+
**Complexity**
|
83
|
+
|
84
|
+
- `O(1)`.
|
85
|
+
|
86
|
+
**Aliases**
|
87
|
+
|
88
|
+
- `get_edge`
|
89
|
+
- `edge`
|
90
|
+
- `[]`
|
91
|
+
|
92
|
+
### edges -> Array([from, to, cap, flow])
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
graph.edges
|
96
|
+
```
|
97
|
+
|
98
|
+
- It returns the current internal state of the all edges.
|
99
|
+
- The edges are ordered in the same order as added by `add_edge`.
|
100
|
+
|
101
|
+
**Complexity**
|
102
|
+
|
103
|
+
- `O(m)`, where `m` is the number of added edges.
|
104
|
+
|
105
|
+
#### Notes on the `edges` method
|
106
|
+
|
107
|
+
The `edges` method is `O(m)` because it generates information for all edges.
|
108
|
+
|
109
|
+
Because of the generation cost, consider using `get_edge(i)` or storing it in a separate variable once, `edges = graph.edges`.
|
110
|
+
|
111
|
+
### change_edge(i, new_cap, new_flow)
|
112
|
+
|
113
|
+
Change the capacity and flow rate of the `i`-th changed edge to `new_cap` and `new_flow`.
|
114
|
+
|
115
|
+
**Constraints**
|
116
|
+
|
117
|
+
- `0 ≤ new_fow ≤ new_cap`
|
118
|
+
|
119
|
+
**Complexity**
|
120
|
+
|
121
|
+
- `O(1)`
|
122
|
+
|
123
|
+
## Verified.
|
124
|
+
|
125
|
+
- [ALPC: D \- Maxflow](https://atcoder.jp/contests/practice2/tasks/practice2_d)
|
126
|
+
- [AC Code 211ms 2020/9/17](https://atcoder.jp/contests/practice2/submissions/16789801)
|
127
|
+
- [ALPC: D \fnDroid Sans Fallback - Qiita](https://qiita.com/magurofly/items/bfaf6724418bfde86bd0)
|
128
|
+
|
129
|
+
## Reference links
|
130
|
+
|
131
|
+
- ac-library-rb
|
132
|
+
- [Code max_flow.rb(GitHub)](https://github.com/universato/ac-library-rb/blob/master/lib/max_flow.rb)
|
133
|
+
- [Test code: max_flow_test.rb(GitHub)](https://github.com/universato/ac-library-rb/blob/master/test/max_flow_test.rb)
|
134
|
+
- The original library AtCoder Library
|
135
|
+
- Code of the original library
|
136
|
+
- [Code: maxflow.hpp(GitHub)](https://github.com/atcoder/ac-library/blob/master/atcoder/maxflow.hpp)
|
137
|
+
- [Test code: maxflow_test.cpp(GitHub)](https://github.com/atcoder/ac-library/blob/master/test/unittest/maxflow_test.cpp)
|
138
|
+
- Main family documentation
|
139
|
+
- [Documentat: maxflow.md(GitHub)](https://github.com/atcoder/ac-library/blob/master/document_en/maxflow.md)
|
140
|
+
- [Documentat: maxflow.html](https://atcoder.github.io/ac-library/document_en/maxflow.html)
|
141
|
+
- [Document: appendix.md(GitHub)](https://github.com/atcoder/ac-library/blob/master/document_en/appendix.md)
|
142
|
+
|
143
|
+
## Questions and Answers.
|
144
|
+
|
145
|
+
### Why does the `flow_limit` of the `flow` method default to `1 << 64`?
|
146
|
+
|
147
|
+
I don't remember, and there is no deeper meaning.
|
148
|
+
It looks like `Float::MAX` or `Float::INFINITY` might be OK, but won't it slow things down?
|
149
|
+
|
150
|
+
### Don't use Struct for edges.
|
151
|
+
|
152
|
+
Using Struct makes the code slimmer, more advanced, and better looking.
|
153
|
+
|
154
|
+
However, as a result of measurements, Struc is slow, so we use arrays.
|
155
|
+
|
156
|
+
### What is the purpose of a variable that starts with `_`?
|
157
|
+
|
158
|
+
It's a bit confusing, but there are two separate intentions: 1.
|
159
|
+
|
160
|
+
1. `_e` and `_re` are matching variable names to make them easier to read with the original ACL code. 2.
|
161
|
+
2. `_rev` is spit out but not used for the convenience of running `each`, so it starts with `_` with the intention of "not using".
|
162
|
+
|
163
|
+
````ruby
|
164
|
+
@g[q].each do |(to, _rev, cap)|
|
165
|
+
````
|
@@ -0,0 +1,132 @@
|
|
1
|
+
# MinCostFlow
|
2
|
+
|
3
|
+
It solves [Minimum\-cost flow problem](https://en.wikipedia.org/wiki/Minimum-cost_flow_problem).
|
4
|
+
|
5
|
+
## Class Methods.
|
6
|
+
|
7
|
+
### new(n = 0) -> MinCostFlow
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
graph = MinCostFlow.new(10)
|
11
|
+
```
|
12
|
+
|
13
|
+
It creates a directed graph with `n` vertices and `0` edges.
|
14
|
+
|
15
|
+
Verticle order is the 0-based index.
|
16
|
+
|
17
|
+
**Constraints**
|
18
|
+
|
19
|
+
- `0 ≦ n`
|
20
|
+
|
21
|
+
**Complexity**
|
22
|
+
|
23
|
+
- `O(n)`
|
24
|
+
|
25
|
+
|
26
|
+
## Instance Methods.
|
27
|
+
|
28
|
+
### add_edge(from, to, cap, cost) -> Integer
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
graph.add_edge(0, 1, 5)
|
32
|
+
```
|
33
|
+
|
34
|
+
Adds an edge from vertex `from` to vertex `to` with maximum capacity `cap` and flow rate `0`.
|
35
|
+
|
36
|
+
The return value is the number of edge added with 0-based index.
|
37
|
+
|
38
|
+
### flow(start, to, flow_limit = Float::MAX) -> [flow, cost]
|
39
|
+
### min_cost_max_flow(start, to, flow_limit = Float::MAX) -> [flow, cost]
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
(1) graph.flow(0, 3)
|
43
|
+
(2) graph.flow(0, 3, flow_limit)
|
44
|
+
```
|
45
|
+
|
46
|
+
The internals are mostly the `slope` method, just getting the last element of the return value of the `slop` method. The constraints and computational complexity are the same as for the `slope` method.
|
47
|
+
|
48
|
+
**Aliases**
|
49
|
+
|
50
|
+
- `flow`
|
51
|
+
- `min_cost_max_flow`
|
52
|
+
|
53
|
+
### slope(s, t, flow_limit = Float::MAX) -> [[flow, cost]]
|
54
|
+
### min_cost_slop(s, t, flow_limit = Float::MAX) -> [[flow, cost]]
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
graph.slop(0, 3)
|
58
|
+
```
|
59
|
+
|
60
|
+
**Complexity**
|
61
|
+
|
62
|
+
- `O(F(n + m) log n)`, where `F` is the amount of the flow and `m` is the number of added edges.
|
63
|
+
|
64
|
+
**Aliases**
|
65
|
+
|
66
|
+
- `slope`
|
67
|
+
- `min_cost_slope`
|
68
|
+
|
69
|
+
### get_edge(i) -> [from, to, cap, flow, cost]
|
70
|
+
### edge(i) -> [from, to, cap, flow, cost]
|
71
|
+
### [](i) -> [from, to, cap, flow, cost]
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
graph.get_edge(i)
|
75
|
+
graph.edge(i)
|
76
|
+
graph[i].
|
77
|
+
```
|
78
|
+
|
79
|
+
It returns the state of the `i`-th edge.
|
80
|
+
|
81
|
+
**Constraints**
|
82
|
+
|
83
|
+
- `0 ≤ i < m`.
|
84
|
+
|
85
|
+
**Complexity**
|
86
|
+
|
87
|
+
- `O(1)`
|
88
|
+
|
89
|
+
### edges -> Array[from, to, cap, flow, cost]
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
graph.edges
|
93
|
+
```
|
94
|
+
|
95
|
+
It returns an array containing information on all edges.
|
96
|
+
|
97
|
+
**Complexity**
|
98
|
+
|
99
|
+
- `O(m)`, where mm is the number of added edges.
|
100
|
+
|
101
|
+
## Verified
|
102
|
+
|
103
|
+
- [ALPC: E\- MinCostFlow](https://atcoder.jp/contests/practice2/tasks/practice2_e)
|
104
|
+
- [1213ms 2020/9/17](https://atcoder.jp/contests/practice2/submissions/16792967)
|
105
|
+
|
106
|
+
## Reference links
|
107
|
+
|
108
|
+
- Our library: ac-library-rb
|
109
|
+
- [Code: min_cost_flow.rb](https://github.com/universato/ac-library-rb/blob/master/lib/min_cost_flow.rb)
|
110
|
+
- [Test code: min_cost_flow_test.rb](https://github.com/universato/ac-library-rb/blob/master/test/min_cost_flow_test.rb)
|
111
|
+
- The original library: AtCoder Library(ACL)
|
112
|
+
- [Documentat: mincostflow.md(GitHub)](https://github.com/atcoder/ac-library/blob/master/document_ja/mincostflow.md)
|
113
|
+
- [Code: mincostflow.hpp(GitHub)](https://github.com/atcoder/ac-library/blob/master/atcoder/mincostflow.hpp)
|
114
|
+
- [Test code: mincostflow_test.cpp(GitHub)](https://github.com/atcoder/ac-library/blob/master/test/unittest/mincostflow_test.cpp )
|
115
|
+
|
116
|
+
## Questions and Answers
|
117
|
+
|
118
|
+
## The intent of the aliases is to
|
119
|
+
|
120
|
+
The method name of the minimum cost flow of the original library is long, so I have an alias for it. The method name of the maximum cost stream in the original library is short, so it is strange.
|
121
|
+
|
122
|
+
### What is the purpose of using `Float::MAX` instead of `Float::INFINITY`?
|
123
|
+
|
124
|
+
I haven't tested it specifically, so I'd like to verify what number is good.
|
125
|
+
|
126
|
+
I felt that the `Integer` class would be fine.
|
127
|
+
|
128
|
+
### Don't use Struct on the edges.
|
129
|
+
|
130
|
+
Using Struct makes the code slimmer and more advanced, and it looks better.
|
131
|
+
|
132
|
+
However, I didn't use Struct because it was too slow as a result of measurement.
|