Here is my entry for the Code Jam problem Full Binary Tree (I didn't compete but tackled the problem afterwards). It does solve the provided inputs, so I suppose it is correct. I am looking for any suggestions regarding the code. One thing I don't like is the fact that the Node constructor clears the array that it receives as a parameter, do you see a clean way to fix this ? Is it possible without declaring an extra class wrapping Node ?
import java.util.*;
class Node {
static NodeComparator cmp = new NodeComparator();
private ArrayList<Node> children = new ArrayList<>();
private int nDescendants = 0; // descendants = number of children and, recursively, children of children, etc.
public int getNDescendants() {
return nDescendants;
}
// turns the tree into a full binary tree by removing as few nodes as possible
public void makeFullBinary() {
// first, recursively make all the children into full binary trees
for (Node n : children) {
n.makeFullBinary();
}
// sort the children from least to most number of descendants
Collections.sort(children, cmp);
// remove descendants as needed to end up with 0 or 2
while ((children.size() != 0) && (children.size() != 2)) {
children.remove(0);
}
// recompute the number of descendants
nDescendants = 0;
for (Node c : children) {
nDescendants += 1 + c.getNDescendants();
}
}
// builds a tree from an array of booleans (adjacency matrix)
// edges is destroyed after the constructor is called
public Node(boolean[][] edges, int root) {
for (int i = 0; i < edges.length; i++) {
if (edges[root][i]) {
edges[root][i] = false;
edges[i][root] = false;
children.add(new Node(edges, i));
}
}
for (Node c : children) {
nDescendants += 1 + c.getNDescendants();
}
}
}
// comparator for sorting only
class NodeComparator implements Comparator<Node> {
@Override
public int compare(Node n0, Node n1) {
return n0.getNDescendants() - n1.getNDescendants();
}
}
public class Program {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int nCases = in.nextInt();
in.nextLine();
for (int caseNumber = 1; caseNumber <= nCases; caseNumber++) {
int nNodes = in.nextInt();
in.nextLine();
boolean[][] edges = new boolean[nNodes][nNodes];
for (int i = 0; i < nNodes-1; i++) {
String[] s = in.nextLine().split(" ");
int x = Integer.parseInt(s[0])-1;
int y = Integer.parseInt(s[1])-1;
edges[x][y] = true;
edges[y][x] = true;
}
int maxDescendants = 0;
boolean [][] e = new boolean[nNodes][nNodes];
for (int i = 0; i < nNodes; i++) {
for (int a = 0; a < nNodes; a++) {
for (int b = 0; b < nNodes; b++) {
e[a][b] = edges[a][b];
}
}
Node tree = new Node(e, i);
tree.makeFullBinary();
maxDescendants = Math.max(maxDescendants, tree.getNDescendants());
}
System.out.print("Case #");
System.out.print(caseNumber);
System.out.print(": ");
System.out.println(nNodes - maxDescendants - 1);
}
in.close();
}
}