@@ -111,11 +111,62 @@ void testSingleNode() {
111111 void testInvalidInputThrowsException () {
112112 List <Edmonds .Edge > edges = new ArrayList <>();
113113
114- assertThrows (IllegalArgumentException .class ,
115- () -> Edmonds .findMinimumSpanningArborescence (0 , edges , 0 ));
116- assertThrows (IllegalArgumentException .class ,
117- () -> Edmonds .findMinimumSpanningArborescence (5 , edges , -1 ));
118- assertThrows (IllegalArgumentException .class ,
119- () -> Edmonds .findMinimumSpanningArborescence (5 , edges , 5 ));
114+ assertThrows (IllegalArgumentException .class , () -> Edmonds .findMinimumSpanningArborescence (0 , edges , 0 ));
115+ assertThrows (IllegalArgumentException .class , () -> Edmonds .findMinimumSpanningArborescence (5 , edges , -1 ));
116+ assertThrows (IllegalArgumentException .class , () -> Edmonds .findMinimumSpanningArborescence (5 , edges , 5 ));
120117 }
121- }
118+
119+ @ Test
120+ void testCoverageForEdgeSelectionLogic () {
121+ int n = 3 ;
122+ int root = 0 ;
123+ List <Edmonds .Edge > edges = new ArrayList <>();
124+
125+ // This will cover the `edge.weight < minWeightEdge[edge.to]` being false.
126+ edges .add (new Edmonds .Edge (0 , 1 , 10 ));
127+ edges .add (new Edmonds .Edge (2 , 1 , 20 ));
128+
129+ // This will cover the `edge.to != root` being false.
130+ edges .add (new Edmonds .Edge (1 , 0 , 100 ));
131+
132+ // A regular edge to make the graph complete
133+ edges .add (new Edmonds .Edge (0 , 2 , 5 ));
134+
135+ // Expected MSA: (0,1, w=10) and (0,2, w=5). Total weight = 15.
136+ long result = Edmonds .findMinimumSpanningArborescence (n , edges , root );
137+ assertEquals (15 , result );
138+ }
139+
140+ @ Test
141+ void testCoverageForContractedSelfLoop () {
142+ int n = 4 ;
143+ int root = 0 ;
144+ List <Edmonds .Edge > edges = new ArrayList <>();
145+
146+ // Connect root to the cycle components
147+ edges .add (new Edmonds .Edge (0 , 1 , 20 ));
148+
149+ // Create a cycle 1 -> 2 -> 1
150+ edges .add (new Edmonds .Edge (1 , 2 , 5 ));
151+ edges .add (new Edmonds .Edge (2 , 1 , 5 ));
152+
153+ // This is the CRITICAL edge for coverage:
154+ // It connects two nodes (1 and 2) that are part of the SAME cycle.
155+ // After contracting cycle {1, 2} into a supernode C, this edge becomes (C, C),
156+ // which means newU == newV. This will trigger the `false` branch of the `if`.
157+ edges .add (new Edmonds .Edge (1 , 1 , 100 )); // Also a self-loop on a cycle node.
158+
159+ // Add another edge to ensure node 3 is reachable
160+ edges .add (new Edmonds .Edge (1 , 3 , 10 ));
161+
162+ // Cycle {1,2} has cost 5+5=10.
163+ // Contract {1,2} to supernode C.
164+ // Edge (0,1,20) becomes (0,C, w=20-5=15).
165+ // Edge (1,3,10) becomes (C,3, w=10).
166+ // Edge (1,1,100) is discarded because newU == newV.
167+ // Cost of contracted graph = 15 + 10 = 25.
168+ // Total cost = cycle cost + contracted cost = 10 + 25 = 35.
169+ long result = Edmonds .findMinimumSpanningArborescence (n , edges , root );
170+ assertEquals (35 , result );
171+ }
172+ }
0 commit comments