1- /** WIP */
21package com .williamfiset .algorithms .graphtheory ;
32
43import java .util .*;
54
65public class Boruvkas {
76
8- static class Edge {
7+ static class Edge implements Comparable < Edge > {
98 int u , v , cost ;
109
1110 public Edge (int u , int v , int cost ) {
@@ -14,11 +13,12 @@ public Edge(int u, int v, int cost) {
1413 this .cost = cost ;
1514 }
1615
16+ @ Override
1717 public String toString () {
1818 return String .format ("%d %d, cost: %d" , u , v , cost );
1919 }
2020
21- // @Override
21+ @ Override
2222 public int compareTo (Edge other ) {
2323 int cmp = cost - other .cost ;
2424 // Break ties by picking lexicographically smallest edge pair.
@@ -32,7 +32,7 @@ public int compareTo(Edge other) {
3232 }
3333
3434 // Inputs
35- private final int n , m ; // Num nodes, num edges
35+ private final int n ; // Number of nodes
3636 private final Edge [] graph ; // Edge list
3737
3838 // Internal
@@ -43,11 +43,10 @@ public int compareTo(Edge other) {
4343 private long minCostSum ;
4444 private List <Edge > mst ;
4545
46- public Boruvkas (int n , int m , Edge [] graph ) {
46+ public Boruvkas (int n , Edge [] graph ) {
4747 if (graph == null ) throw new IllegalArgumentException ();
4848 this .graph = graph ;
4949 this .n = n ;
50- this .m = m ;
5150 }
5251
5352 // Returns the edges used in finding the minimum spanning tree, or returns
@@ -69,62 +68,43 @@ private void solve() {
6968 if (solved ) return ;
7069
7170 mst = new ArrayList <>();
72-
7371 UnionFind uf = new UnionFind (n );
7472
75- int [] cheapest = new int [n ];
76- Arrays .fill (cheapest , -1 );
77-
78- // Repeat at most log(n) times or until we have a complete spanning tree.
79- // for(int t = 1; t < N && index < n - 1; t = t + t) {
80- // for(long t = 1; t <= n && mst.size() != n-1; t = t << 1) {
81- for (; mst .size () != n - 1 ; ) {
82-
83- // TODO: Remove
84- Arrays .fill (cheapest , -1 );
85- boolean stop = true ;
86-
87- for (int i = 0 ; i < graph .length ; i ++) {
88- Edge e = graph [i ];
89- if (e .u == e .v ) continue ;
90- int uc = uf .id [e .u ], vc = uf .id [e .v ];
91- if (uc == vc ) continue ;
92- // if (cheapest[vc] == -1 || e.compareTo(graph[cheapest[vc]]) < 0) { stop = false;
93- // cheapest[vc] = i; }
94- // if (cheapest[uc] == -1 || e.compareTo(graph[cheapest[uc]]) < 0) { stop = false;
95- // cheapest[uc] = i; }
96- if (cheapest [vc ] == -1 || e .cost < graph [cheapest [vc ]].cost ) {
97- stop = false ;
98- cheapest [vc ] = i ;
73+ while (uf .components > 1 ) {
74+ Edge [] cheapest = new Edge [n ];
75+
76+ // Find the cheapest edge for each component
77+ for (Edge e : graph ) {
78+ int root1 = uf .find (e .u );
79+ int root2 = uf .find (e .v );
80+ if (root1 == root2 ) continue ;
81+
82+ if (cheapest [root1 ] == null || e .cost < cheapest [root1 ].cost ) {
83+ cheapest [root1 ] = e ;
9984 }
100- if (cheapest [uc ] == -1 || e .cost < graph [cheapest [uc ]].cost ) {
101- stop = false ;
102- cheapest [uc ] = i ;
85+ if (cheapest [root2 ] == null || e .cost < cheapest [root2 ].cost ) {
86+ cheapest [root2 ] = e ;
10387 }
10488 }
10589
106- if (stop ) break ;
107-
90+ // Add the cheapest edges to the MST
10891 for (int i = 0 ; i < n ; i ++) {
109- if (cheapest [i ] == -1 ) continue ;
110- Edge e = graph [cheapest [i ]];
111- // cheapest[i] = -1;
112- if (uf .connected (e .u , e .v )) continue ;
113-
114- mst .add (e );
115- minCostSum += e .cost ;
116- uf .union (e .u , e .v );
117-
118- // TODO(williamfiset): Optimization is to remove e from graph.
92+ Edge e = cheapest [i ];
93+ if (e == null ) {
94+ continue ;
95+ }
96+ int root1 = uf .find (e .u );
97+ int root2 = uf .find (e .v );
98+ if (root1 != root2 ) {
99+ uf .union (root1 , root2 );
100+ mst .add (e );
101+ minCostSum += e .cost ;
102+ }
119103 }
120104 }
121105
122- // if ( (index==n-1) != (uf.size(0) == n) ) throw new NullPointerException();
123-
124- mstExists = (mst .size () == n - 1 ); // (uf.size(0) == n);
106+ mstExists = (mst .size () == n - 1 );
125107 solved = true ;
126-
127- // if (!check()) throw new IllegalStateException();
128108 }
129109
130110 private boolean check () {
@@ -200,7 +180,7 @@ public static void main(String[] args) {
200180 g [i ++] = new Edge (7 , 8 , 6 );
201181 g [i ++] = new Edge (9 , 8 , 0 );
202182
203- Boruvkas solver = new Boruvkas (n , m , g );
183+ Boruvkas solver = new Boruvkas (n , g );
204184
205185 Long ans = solver .getMstCost ();
206186 if (ans != null ) {
@@ -211,9 +191,6 @@ public static void main(String[] args) {
211191 } else {
212192 System .out .println ("No MST exists" );
213193 }
214-
215- // System.out.println(solver.solve(g, n));
216-
217194 }
218195
219196 // Union find data structure
0 commit comments