ac-library-rb 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|