import java.util.*; import java.util.stream.Stream; public class TreeCenters { // returns 1 or 2 tree centers // http://en.wikipedia.org/wiki/Graph_center public static List findTreeCenters(List[] tree) { int n = tree.length; List leaves = new ArrayList<>(); int[] degree = new int[n]; for (int i = 0; i < n; i++) { degree[i] = tree[i].size(); if (degree[i] <= 1) { leaves.add(i); } } int removedLeaves = leaves.size(); while (removedLeaves < n) { List nleaves = new ArrayList<>(); for (int u : leaves) { for (int v : tree[u]) { if (--degree[v] == 1) { nleaves.add(v); } } } leaves = nleaves; removedLeaves += leaves.size(); } return leaves; } // returns vertex that has all its subtrees sizes <= n/2 public static int findTreeCentroid(List[] tree, int u, int p) { int n = tree.length; int cnt = 1; boolean goodCenter = true; for (int v : tree[u]) { if (v == p) continue; int res = findTreeCentroid(tree, v, u); if (res >= 0) return res; int size = -res; goodCenter &= size <= n / 2; cnt += size; } goodCenter &= n - cnt <= n / 2; return goodCenter ? u : -cnt; } public static int diameter(List[] tree) { int furthestVertex = (int) dfs(tree, 0, -1, 0); return (int) (dfs(tree, furthestVertex, -1, 0) >>> 32); } static long dfs(List[] tree, int u, int p, int depth) { long res = ((long) depth << 32) + u; for (int v : tree[u]) if (v != p) res = Math.max(res, dfs(tree, v, u, depth + 1)); return res; } // Usage example public static void main(String[] args) { int n = 4; List[] tree = Stream.generate(ArrayList::new).limit(n).toArray(List[]::new); tree[3].add(0); tree[0].add(3); tree[3].add(1); tree[1].add(3); tree[3].add(2); tree[2].add(3); System.out.println(3 == findTreeCentroid(tree, 0, -1)); System.out.println(3 == findTreeCenters(tree).get(0)); System.out.println(2 == diameter(tree)); } }