@@ -76,98 +76,160 @@ The **MCMF** algorithm is an algorithm for solving network flow problems.
76
76
77
77
## Usage
78
78
79
- * Codeforces contest 1082 Problem G (https://codeforces.com/contest/1082 /problem/G ):
79
+ * Codeforces contest 0277 Problem E (https://codeforces.com/contest/277 /problem/E ):
80
80
81
81
``` typescript
82
82
import { createMcmf } from ' @algorithm.ts/mcmf'
83
83
84
84
const mcmf = createMcmf ()
85
+ export function solveCodeforces0277E(coordinates : Array <[x : number , y : number ]>): number {
86
+ const N: number = coordinates .length
85
87
86
- // The implementation of `io` is omitted.
87
- function solve(io : any ): number {
88
- const [n, m] = io .readIntegersOfLine ()
88
+ const vertexes: IVertex [] = coordinates
89
+ .map (([x , y ]) => ({ x , y }))
90
+ .sort ((p , q ) => {
91
+ if (p .y === q .y ) return p .x - q .x
92
+ return q .y - p .y
93
+ })
94
+
95
+ const source = 0
96
+ const target: number = N * 2 + 1
97
+ mcmf .init (source , target , N * 2 + 2 )
98
+
99
+ for (let i = 0 ; i < N ; ++ i ) {
100
+ mcmf .addEdge (source , i + 1 , 2 , 0 )
101
+ mcmf .addEdge (N + i + 1 , target , 1 , 0 )
102
+ for (let j = i + 1 ; j < N ; ++ j ) {
103
+ if (vertexes [i ].y === vertexes [j ].y ) continue
104
+ mcmf .addEdge (i + 1 , N + j + 1 , 1 , dist (vertexes [i ], vertexes [j ]))
105
+ }
106
+ }
107
+
108
+ const [mincost, maxflow] = mcmf .minCostMaxFlow ()
109
+ const answer = maxflow === N - 1 ? mincost : - 1
110
+ return answer
111
+ }
112
+
113
+ function dist(p : IVertex , q : IVertex ): number {
114
+ const d = (p .x - q .x ) * (p .x - q .x ) + (p .y - q .y ) * (p .y - q .y )
115
+ return Math .sqrt (d )
116
+ }
117
+
118
+ interface IVertex {
119
+ x: number
120
+ y: number
121
+ }
122
+ ```
123
+
124
+
125
+ * A solution for Codeforces contest 1082 Problem G (https://codeforces.com/contest/1082/problem/G ):
126
+
127
+ ``` typescript
128
+ import { createMcmf } from ' @algorithm.ts/mcmf'
129
+
130
+ const mcmf = createMcmf ()
131
+ export function solveCodeforces1082G(
132
+ nodes : number [],
133
+ edges : Array <[u : number , v : number , weight : number ]>,
134
+ ): number {
135
+ const n: number = nodes .length
136
+ const m: number = edges .length
89
137
90
138
const source = 0
91
139
const target: number = n + m + 1
92
- mcmf .init (source , target , n + m + 2 , n + m * 3 )
140
+ mcmf .init (source , target , n + m + 2 )
93
141
94
- const nodes: number [] = io .readIntegersOfLine ()
95
142
for (let i = 0 ; i < n ; ++ i ) {
96
143
const weight: number = nodes [i ]
97
- mcmf .addEdge (i + 1 , target , weight , 1 )
144
+ mcmf .addEdge (i + 1 , target , weight , 0 )
98
145
}
99
146
100
147
let answer = 0
101
- for (let i = 1 ; i <= m ; ++ i ) {
102
- const [u, v, weight] = io . readIntegersOfLine ()
148
+ for (let i = 0 ; i < m ; ++ i ) {
149
+ const [u, v, weight] = edges [ i ]
103
150
const x = n + i
104
151
answer += weight
105
- mcmf .addEdge (source , x , weight , 1 )
106
- mcmf .addEdge (x , u , Number .MAX_SAFE_INTEGER, 1 )
107
- mcmf .addEdge (x , v , Number .MAX_SAFE_INTEGER, 1 )
152
+ mcmf .addEdge (source , x , weight , 0 )
153
+ mcmf .addEdge (x , u , Number .MAX_SAFE_INTEGER, 0 )
154
+ mcmf .addEdge (x , v , Number .MAX_SAFE_INTEGER, 0 )
108
155
}
109
-
110
- const [mincost, maxflow] = mcmf .minCostMaxFlow ()
111
- answer -= maxflow
156
+ answer -= mcmf .maxFlow ()
112
157
return answer
113
158
}
114
159
```
115
160
116
- * Codeforces contest 0277 Problem E (https://codeforces .com/contest/277/problem/E ):
161
+ * A solution for leetcode "Maximum Students Taking Exam" (https://leetcode .com/problems/maximum-students-taking-exam/ ):
117
162
118
163
``` typescript
119
164
import { createMcmf } from ' @algorithm.ts/mcmf'
120
165
121
- const mcmf = createMcmf ()
166
+ export function maxStudents(seats : string [][]): number {
167
+ const R: number = seats .length
168
+ if (R <= 0 ) return 0
122
169
123
- // The implementation of `io` is omitted.
124
- function solve(io : any ): number {
125
- const [N] = io .readIntegersOfLine ()
170
+ const C: number = seats [0 ].length
171
+ if (C <= 0 ) return 0
126
172
127
- const vertexes: Vertex [] = new Array (N )
128
- for (let i = 0 ; i < N ; ++ i ) {
129
- const [x, y] = io .readIntegersOfLine ()
130
- vertexes [i ] = { x , y }
131
- }
132
- vertexes .sort ((p , q ) => {
133
- if (p .y === q .y ) return p .x - q .x
134
- return q .y - p .y
135
- })
136
-
137
- const source = 0
138
- const target: number = N * 2 + 1
139
- mcmf .init (source , target , N * 2 + 2 , N * N + 2 * N )
173
+ let total = 0
174
+ const seatCodes: number [][] = new Array (R )
175
+ for (let r = 0 ; r < R ; ++ r ) seatCodes [r ] = new Array (C ).fill (- 1 )
140
176
141
- for (let i = 0 ; i < N ; ++ i ) {
142
- mcmf .addEdge (source , i + 1 , 2 , 0 )
143
- mcmf .addEdge (N + i + 1 , target , 1 , 0 )
144
- for (let j = i + 1 ; j < N ; ++ j ) {
145
- if (vertexes [i ].y === vertexes [j ].y ) continue
146
- mcmf .addEdge (i + 1 , N + j + 1 , 1 , dist (vertexes [i ], vertexes [j ]))
177
+ for (let r = 0 ; r < R ; ++ r ) {
178
+ for (let c = 0 ; c < C ; ++ c ) {
179
+ if (seats [r ][c ] === ' .' ) seatCodes [r ][c ] = total ++
147
180
}
148
181
}
149
182
150
- const [mincost, maxflow] = mcmf .minCostMaxFlow ()
151
- const answer = maxflow === N - 1 ? mincost : - 1
152
- return answer
153
- }
154
-
155
- function dist(p : Vertex , q : Vertex ): number {
156
- const d = (p .x - q .x ) * (p .x - q .x ) + (p .y - q .y ) * (p .y - q .y )
157
- return Math .sqrt (d )
158
- }
183
+ if (total <= 0 ) return 0
184
+ if (total === 1 ) return 1
185
+
186
+ const source: number = total * 2
187
+ const target: number = source + 1
188
+ const mcmf = createMcmf ()
189
+ mcmf .init (source , target , target + 1 )
190
+
191
+ for (let r = 0 ; r < R ; ++ r ) {
192
+ for (let c = 0 ; c < C ; ++ c ) {
193
+ const u: number = seatCodes [r ][c ]
194
+ if (u > - 1 ) {
195
+ mcmf .addEdge (source , u , 1 , 0 )
196
+ mcmf .addEdge (u + total , target , 1 , 0 )
197
+ if (r > 0 ) {
198
+ // Check upper left
199
+ if (c > 0 && seatCodes [r - 1 ][c - 1 ] > - 1 ) {
200
+ const v: number = seatCodes [r - 1 ][c - 1 ]
201
+ mcmf .addEdge (u , v + total , 1 , 0 )
202
+ mcmf .addEdge (v , u + total , 1 , 0 )
203
+ }
204
+
205
+ // Check upper right
206
+ if (c + 1 < C && seatCodes [r - 1 ][c + 1 ] > - 1 ) {
207
+ const v: number = seatCodes [r - 1 ][c + 1 ]
208
+ mcmf .addEdge (u , v + total , 1 , 0 )
209
+ mcmf .addEdge (v , u + total , 1 , 0 )
210
+ }
211
+ }
212
+
213
+ // Check left
214
+ if (c > 0 && seatCodes [r ][c - 1 ] > - 1 ) {
215
+ const v: number = seatCodes [r ][c - 1 ]
216
+ mcmf .addEdge (u , v + total , 1 , 0 )
217
+ mcmf .addEdge (v , u + total , 1 , 0 )
218
+ }
219
+ }
220
+ }
221
+ }
159
222
160
- interface Vertex {
161
- x: number
162
- y: number
223
+ const totalPaired: number = mcmf .maxFlow () / 2
224
+ return total - totalPaired
163
225
}
164
226
```
165
227
166
228
## Related
167
229
168
230
169
231
* [ @algorithm .ts/dinic] ( https://github.com/guanghechen/algorithm.ts/tree/main/packages/dinic )
170
- * [ @algorithm .ts/isap ] ( https://github.com/guanghechen/algorithm.ts/tree/main/packages/isap )
232
+ * [ @algorithm .ts/mcmf ] ( https://github.com/guanghechen/algorithm.ts/tree/main/packages/mcmf )
171
233
* [ 网络流 24 题] ( https://me.guanghechen.com/post/algorithm/graph/network-flow/24-problems/ )
172
234
* [ 网络流基础之最大权闭合图] ( https://me.guanghechen.com/post/algorithm/graph/network-flow/%E6%9C%80%E5%A4%A7%E6%9D%83%E9%97%AD%E5%90%88%E5%9B%BE/ )
173
235
0 commit comments