// Solution to "Countdown" by Bob Roos // import java.util.*; import java.io.*; public class BCountdown { public static class Node { public String name; // this person's name public int m; // number of children public Node[] child; // array of children public int count; public Node(String name) { this(name,0); } public void createChildren(int m) { this.m = m; child = new Node[m]; } public Node(String name, int m) { this.name = name; this.m = m; child = new Node[m]; count = 0; } } public static BufferedReader in; public static StringTokenizer tok; public static int caseNum; public static int numCases; public static int n,d; public static Hashtable person; public static Node[] nodeArray; public static int na; public static void main(String[] args) throws IOException { in = new BufferedReader(new InputStreamReader(System.in)); caseNum = 0; // How many test cases? numCases = Integer.parseInt(in.readLine().trim()); for (int i = 0; i < numCases; i++) { caseNum++; person = new Hashtable(); String line = in.readLine().trim(); tok = new StringTokenizer(line); n = Integer.parseInt(tok.nextToken()); d = Integer.parseInt(tok.nextToken()); // Read in node information, one node at a time: for (int j = 0; j < n; j++) { line = in.readLine().trim(); tok = new StringTokenizer(line); String name = tok.nextToken(); int m = Integer.parseInt(tok.nextToken()); Node p = (Node)person.get(name); if (p == null) { p = new Node(name,m); person.put(name,p); } else p.createChildren(m); // Get all children of this node: for (int k = 0; k < m; k++) { String child = tok.nextToken(); Node q = (Node)person.get(child); if (q == null) { q = new Node(child); person.put(child,q); } p.child[k] = q; } } Collection nodeCollection = person.values(); Iterator personIter = nodeCollection.iterator(); nodeArray = new Node[person.size()]; na = 0; while(personIter.hasNext()) { Node node = (Node)personIter.next(); int ans = recur(node,d); node.count = ans; insert(node,ans); } if (caseNum > 1) System.out.println(); System.out.println("Tree " + caseNum + ":"); int printed = 0; int k = 0; while (printed < 3 && k < na && nodeArray[k].count > 0) { int current = nodeArray[k].count; System.out.println(nodeArray[k].name + " " + nodeArray[k].count); printed++; k++; while (k < na && nodeArray[k].count == current) { System.out.println(nodeArray[k].name + " " + nodeArray[k].count); printed++; k++; } } } } public static int recur(Node node, int d) { if (d == 1) { return node.m; } int sum = 0; for (int i = 0; i < node.m; i++) { sum += recur(node.child[i],d-1); } return sum; } public static void insert(Node node, int ans) { int i = na-1; while (i >= 0 && nodeArray[i].count < ans) { nodeArray[i+1] = nodeArray[i]; i--; } while (i >= 0 && nodeArray[i].count == ans && nodeArray[i].name.compareTo(node.name) > 0) { nodeArray[i+1] = nodeArray[i]; i--; } nodeArray[i+1] = node; na++; } }