@@ -67,9 +67,11 @@ public static int maxFlow(int[][] capacity, int source, int sink) {
6767 }
6868 }
6969
70+ State state = new State (residual , height , excess , nextNeighbor , source , sink , active );
71+
7072 while (!active .isEmpty ()) {
7173 int u = active .poll ();
72- discharge (u , residual , height , excess , nextNeighbor , source , sink , active );
74+ discharge (u , state );
7375 if (excess [u ] > 0 ) {
7476 // still active after discharge; push to back
7577 active .add (u );
@@ -80,34 +82,54 @@ public static int maxFlow(int[][] capacity, int source, int sink) {
8082 return excess [sink ];
8183 }
8284
83- private static boolean discharge (int u , int [][] residual , int [] height , int [] excess , int [] nextNeighbor , int source , int sink , Queue < Integer > active ) {
84- final int n = residual .length ;
85+ private static boolean discharge (int u , State s ) {
86+ final int n = s . residual .length ;
8587 boolean pushedAny = false ;
86- while (excess [u ] > 0 ) {
87- if (nextNeighbor [u ] >= n ) {
88- relabel (u , residual , height );
89- nextNeighbor [u ] = 0 ;
88+ while (s . excess [u ] > 0 ) {
89+ if (s . nextNeighbor [u ] >= n ) {
90+ relabel (u , s . residual , s . height );
91+ s . nextNeighbor [u ] = 0 ;
9092 continue ;
9193 }
92- int v = nextNeighbor [u ];
93- if (residual [u ][v ] > 0 && height [u ] == height [v ] + 1 ) {
94- int delta = Math .min (excess [u ], residual [u ][v ]);
95- residual [u ][v ] -= delta ;
96- residual [v ][u ] += delta ;
97- excess [u ] -= delta ;
98- int prevExcessV = excess [v ];
99- excess [v ] += delta ;
100- if (v != source && v != sink && prevExcessV == 0 ) {
101- active .add (v );
94+ int v = s . nextNeighbor [u ];
95+ if (s . residual [u ][v ] > 0 && s . height [u ] == s . height [v ] + 1 ) {
96+ int delta = Math .min (s . excess [u ], s . residual [u ][v ]);
97+ s . residual [u ][v ] -= delta ;
98+ s . residual [v ][u ] += delta ;
99+ s . excess [u ] -= delta ;
100+ int prevExcessV = s . excess [v ];
101+ s . excess [v ] += delta ;
102+ if (v != s . source && v != s . sink && prevExcessV == 0 ) {
103+ s . active .add (v );
102104 }
103105 pushedAny = true ;
104106 } else {
105- nextNeighbor [u ]++;
107+ s . nextNeighbor [u ]++;
106108 }
107109 }
108110 return pushedAny ;
109111 }
110112
113+ private static final class State {
114+ final int [][] residual ;
115+ final int [] height ;
116+ final int [] excess ;
117+ final int [] nextNeighbor ;
118+ final int source ;
119+ final int sink ;
120+ final Queue <Integer > active ;
121+
122+ State (int [][] residual , int [] height , int [] excess , int [] nextNeighbor , int source , int sink , Queue <Integer > active ) {
123+ this .residual = residual ;
124+ this .height = height ;
125+ this .excess = excess ;
126+ this .nextNeighbor = nextNeighbor ;
127+ this .source = source ;
128+ this .sink = sink ;
129+ this .active = active ;
130+ }
131+ }
132+
111133 private static void relabel (int u , int [][] residual , int [] height ) {
112134 final int n = residual .length ;
113135 int minHeight = Integer .MAX_VALUE ;
0 commit comments