11package com .thealgorithms .graph ;
22
3+ import java .util .Arrays ;
4+
35/**
46 * An implementation of the Stoer-Wagner algorithm to find the global minimum cut of an undirected, weighted graph.
57 * A minimum cut is a partition of the graph's vertices into two disjoint sets with the minimum possible edge weight
@@ -22,85 +24,57 @@ public int findMinCut(int[][] graph) {
2224 return 0 ;
2325 }
2426
25- // Make a working copy of the adjacency matrix so we can merge vertices
26- int [][] g = new int [n ][n ];
27+ int [][] currentGraph = new int [n ][n ];
2728 for (int i = 0 ; i < n ; i ++) {
28- System .arraycopy (graph [i ], 0 , g [i ], 0 , n );
29+ System .arraycopy (graph [i ], 0 , currentGraph [i ], 0 , n );
2930 }
3031
31- // vertices contains the list of active vertex indices (initially 0..n-1)
32- int [] vertices = new int [n ];
33- for (int i = 0 ; i < n ; i ++) {
34- vertices [i ] = i ;
35- }
32+ int minCut = Integer .MAX_VALUE ;
33+ boolean [] merged = new boolean [n ];
3634
37- int bestCut = Integer .MAX_VALUE ;
35+ for (int phase = 0 ; phase < n - 1 ; phase ++) {
36+ boolean [] inSetA = new boolean [n ];
37+ int [] weights = new int [n ];
38+ int prev = -1 ;
39+ int last = -1 ;
3840
39- // Repeat n-1 phases; in each phase we reduce number of active vertices by 1
40- for (int m = n ; m > 1 ; m --) {
41- int [] weights = new int [n ]; // accumulated weights for selection
42- boolean [] added = new boolean [n ]; // which original vertices have been added in this phase
43- int prev = -1 ; // previously added vertex id in the growing set
41+ for (int i = 0 ; i < n - phase ; i ++) {
42+ int maxWeight = -1 ;
43+ int currentVertex = -1 ;
4444
45- for (int i = 0 ; i < m ; i ++) {
46- // Select the not-yet-added vertex (among the first m active vertices) with maximum weight
47- int sel = -1 ;
48- for (int j = 0 ; j < m ; j ++) {
49- int v = vertices [j ];
50- if (!added [v ] && (sel == -1 || weights [v ] > weights [sel ])) {
51- sel = v ;
45+ for (int j = 0 ; j < n ; j ++) {
46+ if (!merged [j ] && !inSetA [j ] && weights [j ] > maxWeight ) {
47+ maxWeight = weights [j ];
48+ currentVertex = j ;
5249 }
5350 }
5451
55- // If sel is -1 it means the graph is disconnected in the remaining part;
56- // the minimum cut value is 0 in that case.
57- if (sel == -1 ) {
52+ if (currentVertex == -1 ) {
53+ // This can happen if the graph is disconnected.
5854 return 0 ;
5955 }
6056
61- added [sel ] = true ;
57+ prev = last ;
58+ last = currentVertex ;
59+ inSetA [last ] = true ;
6260
63- // If this is the last vertex added in this phase, weights[sel] is the cut weight between sel and the rest.
64- if (i == m - 1 ) {
65- // Update best cut
66- if (weights [sel ] < bestCut ) {
67- bestCut = weights [sel ];
61+ for (int j = 0 ; j < n ; j ++) {
62+ if (!merged [j ] && !inSetA [j ]) {
63+ weights [j ] += currentGraph [last ][j ];
6864 }
65+ }
66+ }
6967
70- // Merge 'sel' into 'prev' (combine their edges) to reduce vertex count
71- if (prev != -1 ) {
72- for (int k = 0 ; k < n ; k ++) {
73- // accumulate edges from sel into prev
74- g [prev ][k ] += g [sel ][k ];
75- g [k ][prev ] = g [prev ][k ];
76- }
68+ minCut = Math .min (minCut , weights [last ]);
7769
78- // Remove 'sel' from vertices[] by replacing it with last active vertex
79- int selIndex = -1 ;
80- for (int j = 0 ; j < m ; j ++) {
81- if (vertices [j ] == sel ) {
82- selIndex = j ;
83- break ;
84- }
85- }
86- // replace position selIndex with last active vertex (m-1)
87- vertices [selIndex ] = vertices [m - 1 ];
88- }
89- // Phase done
90- } else {
91- // not last: update weights of remaining active vertices
92- for (int j = 0 ; j < m ; j ++) {
93- int v = vertices [j ];
94- if (!added [v ]) {
95- weights [v ] += g [sel ][v ];
96- }
97- }
98- prev = sel ;
99- }
70+ // Merge 'last' vertex into 'prev' vertex
71+ for (int i = 0 ; i < n ; i ++) {
72+ currentGraph [prev ][i ] += currentGraph [last ][i ];
73+ currentGraph [i ][prev ] = currentGraph [prev ][i ];
10074 }
75+ merged [last ] = true ;
10176 }
10277
103- return bestCut == Integer . MAX_VALUE ? 0 : bestCut ;
78+ return minCut ;
10479 }
10580}
106-
0 commit comments