33import java .util .ArrayList ;
44import java .util .Arrays ;
55import java .util .List ;
6- import java .util .HashMap ;
76
87public class CentroidDecomposition {
98 private List <Integer >[] tree ;
109 private List <Integer >[] centroidTree ;
11- private boolean [] removedCentroids ;
10+ private boolean [] centroidMarked ;
11+ private int [] centroidParent ;
12+ private int startingNode ;
13+ private int N ;
1214
15+ public CentroidDecomposition (int n , int startingNode ){
16+ tree = new ArrayList [n ];
17+ centroidTree = new ArrayList [n ];
18+ N = n ;
19+ for (int i = 0 ; i < centroidTree .length ; i ++) centroidTree [i ] = new ArrayList <>();
20+ for (int i = 0 ; i < tree .length ; i ++) tree [i ] = new ArrayList <>();
21+ centroidMarked = new boolean [n ];
22+ centroidParent = new int [n ];
23+ startingNode = (int )(Math .random () * n +1 );
24+ for (int i = 0 ; i <n ; i ++){
25+ tree [i ] = new ArrayList <>();
26+ }
27+ }
1328 public CentroidDecomposition (int n ){
1429 tree = new ArrayList [n ];
1530 centroidTree = new ArrayList [n ];
16- removedCentroids = new boolean [n ];
31+ centroidMarked = new boolean [n ];
32+ centroidParent = new int [n ];
33+ startingNode = (this .startingNode == -1 ) ? (int )(Math .random () * n +1 ) : this .startingNode ;
34+ N = n ;
35+ for (int i = 0 ; i < centroidTree .length ; i ++) centroidTree [i ] = new ArrayList <>();
36+ for (int i = 0 ; i < tree .length ; i ++) tree [i ] = new ArrayList <>();
1737 for (int i = 0 ; i <n ; i ++){
1838 tree [i ] = new ArrayList <>();
1939 }
2040 }
2141
42+ public List <Integer >[] getCentroidTree (){
43+ return centroidTree ;
44+ }
45+
2246 public void addEdge (int u , int v ){
2347 tree [u ].add (v );
2448 tree [v ].add (u );
2549 }
2650
51+ private void addEdgeCTree (int u , int v ){
52+ centroidTree [u ].add (v );
53+ centroidTree [v ].add (u );
54+ centroidParent [v ] = u ;
55+ }
56+
57+
2758 public void findSubtreeSizes (int src , boolean [] visited , int [] subtreeSizes ){
2859 // dfs traversal to find size of subtree rooted at src
2960 visited [src ] = true ;
3061 subtreeSizes [src ] = 1 ;
3162 for (int node : tree [src ]){
32- if (!visited [node ]){
63+ if (!visited [node ] && ! centroidMarked [ node ] ){
3364 visited [node ] = true ;
3465 findSubtreeSizes (node , visited , subtreeSizes ); // recurse down to last child node
3566 subtreeSizes [src ] += subtreeSizes [node ]; // add size of full recursive path to subtree Size of src
3667 }
3768 }
3869 }
3970
40- private void findCentroid (int src ){
41- int treeSize = tree [src ].size ();
42- int [] subtreeSizes = new int [treeSize ];
43- boolean [] visited = new boolean [treeSize ];
71+ public void findCentroid (int src , int previousCentroid ){
72+ int [] subtreeSizes = new int [N ];
73+ boolean [] visited = new boolean [N ];
4474 Arrays .fill (visited , false );
45-
75+
4676 findSubtreeSizes (src , visited , subtreeSizes );
77+ int treeSize = Arrays .stream (subtreeSizes ).max ().getAsInt ();
78+
79+ centroidMarked [src ] = true ;
4780
48- boolean isCentroid = true ;
4981 for (int node : tree [src ]){
50- isCentroid = (subtreeSizes [node ] <= (subtreeSizes [src ]/2 )) ? true : false ;
82+ if (subtreeSizes [node ] > (treeSize /2 )){
83+ centroidMarked [src ] = false ;
84+ break ;
85+ }
5186 }
52-
53- if (isCentroid ){
87+
88+ if (centroidMarked [src ]){
89+ if (src != startingNode && src != previousCentroid ) addEdgeCTree (previousCentroid , src );
90+ // centroidTree[previousCentroid].add(src);
5491 for (int node : tree [src ]){
55-
92+ if (!centroidMarked [node ])
93+ findCentroid (node , src );
5694 }
5795 }
5896 else {
59- // pick one of the children of the node for next check
97+ // pick one of the children of the root for next check
98+ int nextLargestSubtree = tree [src ].getFirst ();
99+ for (int node : tree [src ]){
100+ if (subtreeSizes [node ] >= subtreeSizes [nextLargestSubtree ])
101+ nextLargestSubtree = node ;
102+ }
103+ findCentroid (nextLargestSubtree , previousCentroid );
60104 }
61105 }
62106
63107 public static void main (String [] args ) {
64- CentroidDecomposition cd = new CentroidDecomposition (16 );
108+ CentroidDecomposition cd = new CentroidDecomposition (16 , - 1 );
65109 cd .addEdge (0 , 1 );
66110 cd .addEdge (0 , 2 );
67111 cd .addEdge (0 , 3 );
@@ -81,7 +125,22 @@ public static void main(String[] args) {
81125 boolean [] visited = new boolean [16 ];
82126 int [] subtreeSizes = new int [16 ];
83127
84- cd .findSubtreeSizes (3 , visited , subtreeSizes );
128+ // int start = cd.startingNode;
129+ int src = (int ) ((Math .random () * (15 )) + 0 );
130+ System .out .println ("src= " + src );
131+
132+ cd .findCentroid (src , src );
133+
134+ // System.out.println((int)(Math.random() * 16));
135+
136+ for (int i = 0 ; i < cd .centroidTree .length ; i ++) {
137+ System .out .println (String .format ("%s %s" , i , cd .centroidTree [i ]));
138+ }
139+
140+ // cd.findSubtreeSizes(8, visited, subtreeSizes);
141+ // for (int i = 0; i < subtreeSizes.length; i++) {
142+ // System.out.println(String.format("%s %s", i, subtreeSizes[i]));
143+ // }
85144 }
86145
87146}
0 commit comments