@@ -3,97 +3,97 @@ import { createCircularQueue } from '@algorithm.ts/circular-queue'
3
3
import type { Dinic , DinicContext , DinicEdge } from './types'
4
4
5
5
export function createDinic ( ) : Dinic {
6
- let source : number // The source point in a network flow
7
- let target : number // The sink in a network flow
8
- let n : number // The number of nodes in a network flow
9
- let m : number // The number of edges in a network flow (not including the reverse edges).
10
- let answer : number
11
- let edgeTot : number
12
- const cur : number [ ] = [ ] // The next edge number to be considered of the edges starting from the i-th node.
13
- const dist : number [ ] = [ ] // The distance from the source node to the i-th node.
14
- const edges : DinicEdge [ ] = [ ]
15
- const G : number [ ] [ ] = [ ]
16
- const Q : CircularQueue < number > = createCircularQueue ( )
17
- return { init, addEdge, maxflow , solve }
6
+ let _source : number // The source point in a network flow
7
+ let _target : number // The sink in a network flow
8
+ let _n : number // The number of nodes in a network flow
9
+ let _m : number // The number of edges in a network flow (not including the reverse edges).
10
+ let _maxflow : number
11
+ let _edgeTot : number
12
+ const _cur : number [ ] = [ ] // The next edge number to be considered of the edges starting from the i-th node.
13
+ const _dist : number [ ] = [ ] // The distance from the source node to the i-th node.
14
+ const _edges : DinicEdge [ ] = [ ]
15
+ const _G : number [ ] [ ] = [ ]
16
+ const _Q : CircularQueue < number > = createCircularQueue ( )
17
+ return { init, addEdge, maxFlow , solve }
18
18
19
- function init (
20
- _source : number ,
21
- _target : number ,
22
- _n : number ,
23
- _m : number ,
24
- ) : void {
25
- source = _source
26
- target = _target
27
- n = _n
28
- m = m << 1
29
- answer = 0
19
+ function init ( source : number , target : number , n : number , m : number ) : void {
20
+ _source = source
21
+ _target = target
22
+ _n = n
23
+ _m = _m << 1
24
+ _maxflow = 0
30
25
31
26
// Resize arrays.
32
- if ( cur . length < n ) cur . length = n
33
- if ( dist . length < n ) dist . length = n
34
- if ( edges . length < m ) edges . length = m
35
- if ( G . length < n ) G . length = n
27
+ if ( _cur . length < _n ) _cur . length = _n
28
+ if ( _dist . length < _n ) _dist . length = _n
29
+ if ( _edges . length < _m ) _edges . length = _m
30
+ if ( _G . length < _n ) _G . length = _n
36
31
37
- edgeTot = 0
38
- Q . init ( n + 1 )
39
- for ( let i = 0 ; i < n ; ++ i ) G [ i ] = [ ]
32
+ _edgeTot = 0
33
+ _Q . init ( _n + 1 )
34
+ for ( let i = 0 ; i < _n ; ++ i ) _G [ i ] = [ ]
40
35
}
41
36
42
37
function addEdge ( from : number , to : number , cap : number ) : void {
43
- G [ from ] . push ( edgeTot )
38
+ _G [ from ] . push ( _edgeTot )
44
39
// eslint-disable-next-line no-plusplus
45
- edges [ edgeTot ++ ] = { from, to, cap, flow : 0 }
40
+ _edges [ _edgeTot ++ ] = { from, to, cap, flow : 0 }
46
41
47
- G [ to ] . push ( edgeTot )
42
+ _G [ to ] . push ( _edgeTot )
48
43
// eslint-disable-next-line no-plusplus
49
- edges [ edgeTot ++ ] = { from : to , to : from , cap : 0 , flow : 0 }
44
+ _edges [ _edgeTot ++ ] = { from : to , to : from , cap : 0 , flow : 0 }
50
45
}
51
46
52
- function maxflow ( ) : number {
47
+ function maxFlow ( ) : number {
53
48
while ( bfs ( ) ) {
54
- cur . fill ( 0 , 0 , n )
55
- answer += dfs ( source , Number . MAX_SAFE_INTEGER )
49
+ _cur . fill ( 0 , 0 , _n )
50
+ _maxflow += dfs ( _source , Number . MAX_SAFE_INTEGER )
56
51
}
57
- return answer
52
+ return _maxflow
58
53
}
59
54
60
55
function solve ( fn : ( context : DinicContext ) => void ) : void {
61
- const context : DinicContext = { edgeTot, dist, edges, G }
56
+ const context : DinicContext = {
57
+ edgeTot : _edgeTot ,
58
+ dist : _dist ,
59
+ edges : _edges ,
60
+ G : _G ,
61
+ }
62
62
fn ( context )
63
63
}
64
64
65
65
function bfs ( ) : boolean {
66
66
// Initialize the dist array.
67
- dist . fill ( - 1 , 0 , n )
67
+ _dist . fill ( - 1 , 0 , _n )
68
68
69
- Q . enqueue ( source )
70
- dist [ source ] = 0
71
- while ( Q . size ( ) > 0 ) {
72
- const o = Q . dequeue ( ) !
73
- for ( const i of G [ o ] ) {
74
- const e = edges [ i ]
75
- if ( dist [ e . to ] === - 1 && e . cap > e . flow ) {
76
- dist [ e . to ] = dist [ o ] + 1
77
- Q . enqueue ( e . to )
69
+ _Q . enqueue ( _source )
70
+ _dist [ _source ] = 0
71
+ while ( _Q . size ( ) > 0 ) {
72
+ const o = _Q . dequeue ( ) !
73
+ for ( const i of _G [ o ] ) {
74
+ const e = _edges [ i ]
75
+ if ( _dist [ e . to ] === - 1 && e . cap > e . flow ) {
76
+ _dist [ e . to ] = _dist [ o ] + 1
77
+ _Q . enqueue ( e . to )
78
78
}
79
79
}
80
80
}
81
81
82
- return dist [ target ] !== - 1
82
+ return _dist [ _target ] !== - 1
83
83
}
84
84
85
85
function dfs ( o : number , minFlow : number ) : number {
86
- if ( o === target || minFlow === 0 ) return minFlow
86
+ if ( o === _target || minFlow === 0 ) return minFlow
87
87
88
88
let flow = 0
89
- for ( let g = G [ o ] ; cur [ o ] < g . length ; ++ cur [ o ] ) {
90
- const x = g [ cur [ o ] ]
91
- const e = edges [ x ]
92
- if ( dist [ e . to ] === dist [ o ] + 1 ) {
89
+ for ( let g = _G [ o ] ; _cur [ o ] < g . length ; ++ _cur [ o ] ) {
90
+ const x = g [ _cur [ o ] ]
91
+ const e = _edges [ x ]
92
+ if ( _dist [ e . to ] === _dist [ o ] + 1 ) {
93
93
const f = dfs ( e . to , Math . min ( minFlow , e . cap - e . flow ) )
94
94
if ( f <= 0 ) continue
95
95
e . flow += f
96
- edges [ x ^ 1 ] . flow -= f
96
+ _edges [ x ^ 1 ] . flow -= f
97
97
flow += f
98
98
// eslint-disable-next-line no-param-reassign
99
99
minFlow -= f
0 commit comments