Advertisement
Guest User

All Subtrees With a Given Sum

a guest
Jan 16th, 2019
284
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 7.02 KB | None | 0 0
  1. package _08SubtreesWithGivenSum;
  2.  
  3. import java.io.BufferedReader;
  4. import java.io.IOException;
  5. import java.io.InputStreamReader;
  6. import java.util.*;
  7. import java.util.stream.Collectors;
  8.  
  9. /**
  10.  * Created by IntelliJ IDEA.
  11.  * User: LAPD
  12.  * Date: 13.1.2019 г.
  13.  * Time: 14:59 ч.
  14.  */
  15. public class Main {
  16.  
  17.     static BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
  18.  
  19.     static Map<Integer, Tree<Integer>> nodeByValue = new HashMap<>();
  20.  
  21.     static Tree<Integer> getTreeNodeByValue(int value) {
  22.         if (!nodeByValue.containsKey(value)) {
  23.             nodeByValue.put(value, new Tree<>(value));
  24.         }
  25.  
  26.         return nodeByValue.get(value);
  27.     }
  28.  
  29.     static void addEdge(int parent, int child) {
  30.         Tree<Integer> parentNode = getTreeNodeByValue(parent);
  31.         Tree<Integer> childNode = getTreeNodeByValue(child);
  32.  
  33.         parentNode.children.add(childNode);
  34.         childNode.parent = parentNode;
  35.     }
  36.  
  37.     static void ReadTree() throws IOException {
  38. //        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
  39.  
  40.         int nodeCount = Integer.parseInt(bufferedReader.readLine());
  41.  
  42.         for (int i = 0; i < nodeCount - 1; i++) {
  43.             int[] edge = Arrays.stream(bufferedReader.readLine()
  44.                     .split("\\s+"))
  45.                     .mapToInt(Integer::parseInt)
  46.                     .toArray();
  47.  
  48.             addEdge(edge[0], edge[1]);
  49.         }
  50.     }
  51.  
  52.     static Tree<Integer> getRootNode() {
  53.         return nodeByValue.values()
  54.                 .stream()
  55.                 .filter(x -> x.parent == null)
  56.                 .findFirst()
  57.                 .get();
  58.     }
  59.  
  60.     static String printTree() {
  61.         return printTree(getRootNode(), 0, new StringBuilder());
  62.     }
  63.  
  64.     static String printTree(Tree<Integer> current, int indent, StringBuilder builder) {
  65.  
  66.         builder.append(String.join("",
  67.                 Collections.nCopies(indent * 2, " ")))
  68.                 .append(current.value)
  69.                 .append("\n");
  70.  
  71.         for (Tree<Integer> child : current.children) {
  72.             printTree(child, indent + 1, builder);
  73.         }
  74.  
  75.         return builder.toString();
  76.  
  77.     }
  78.  
  79.     static List<Tree<Integer>> getLeafNodes() {
  80.         return nodeByValue.values()
  81.                 .stream()
  82.                 .filter(x -> x.children.isEmpty())
  83.                 .collect(Collectors.toList());
  84.     }
  85.  
  86.     static List<Tree<Integer>> getMiddleNodes() {
  87.         return nodeByValue.values()
  88.                 .stream()
  89.                 .filter(x -> !x.children.isEmpty()
  90.                         && x.parent != null)
  91.                 .collect(Collectors.toList());
  92.     }
  93.  
  94.     static Tree<Integer> getDeepestNode() {
  95.         return getDeepestNode(getRootNode(), 0,
  96.                 new TreeMap<>(Collections.reverseOrder()));
  97.     }
  98.  
  99.     private static Tree<Integer> getDeepestNode(Tree<Integer> current,
  100.                                                 int depth, TreeMap<Integer,
  101.             Tree<Integer>> nodeByDepth) {
  102.  
  103.         if (!nodeByDepth.containsKey(depth)) {
  104.             nodeByDepth.put(depth, current);
  105.         }
  106.  
  107.         for (Tree<Integer> child : current.children) {
  108.             getDeepestNode(child, depth + 1, nodeByDepth);
  109.         }
  110.  
  111. //        Collections.max(nodeByDepth.entrySet(),
  112. //                Comparator.comparingInt(Map.Entry::getKey)).getValue();
  113.         return nodeByDepth.firstEntry().getValue();
  114.     }
  115.  
  116.     private static List<Tree<Integer>> getLongestPath() {
  117.         List<Tree<Integer>> path = new ArrayList<>();
  118.  
  119.         Tree<Integer> current = getDeepestNode();
  120.  
  121.         while (current.parent != null) {
  122.             path.add(current);
  123.             current = current.parent;
  124.         }
  125.  
  126.         path.add(current);
  127.  
  128.         Collections.reverse(path);
  129.  
  130.         return path;
  131.     }
  132.  
  133.     private static List<List<Tree<Integer>>> getPathsWithSum(int sum) {
  134.  
  135.         return getPathsWithSum(getRootNode(), 0, sum,
  136.                 new ArrayList<>());
  137.     }
  138.  
  139.     private static List<List<Tree<Integer>>> getPathsWithSum(Tree<Integer> current,
  140.                                                              int currentSum, int targetSum,
  141.                                                              List<List<Tree<Integer>>> result) {
  142.  
  143.         currentSum += current.value;
  144.  
  145.         if (currentSum < targetSum) {
  146.             for (Tree<Integer> child : current.children) {
  147.                 getPathsWithSum(child, currentSum, targetSum,
  148.                         result);
  149.             }
  150.         }
  151.  
  152.         if (currentSum == targetSum) {
  153.             List<Tree<Integer>> sumPath = new ArrayList<>();
  154.  
  155.             Tree<Integer> parent = current;
  156.  
  157.             while (parent.parent != null) {
  158.                 sumPath.add(parent);
  159.                 parent = parent.parent;
  160.             }
  161.  
  162.             sumPath.add(parent);
  163.  
  164.             Collections.reverse(sumPath);
  165.  
  166.             result.add(sumPath);
  167.         }
  168.  
  169.         return result;
  170.     }
  171.  
  172.     private static List<List<Tree<Integer>>> getTreesWithSum(int sum) {
  173.  
  174.         List<Tree<Integer>> subtreeRoots = new ArrayList<>();
  175.  
  176.         getSubtreeRootWithSum(getRootNode(), 0, sum, subtreeRoots);
  177.  
  178.         List<List<Tree<Integer>>> result = new ArrayList<>();
  179.  
  180.         for (Tree<Integer> subtreeRoot : subtreeRoots) {
  181.             List<Tree<Integer>> subtreePath = new ArrayList<>();
  182.  
  183.             getAllChildren(subtreeRoot, subtreePath);
  184.  
  185.             result.add(subtreePath);
  186.         }
  187.  
  188.         return result;
  189.     }
  190.  
  191.     private static void getAllChildren(Tree<Integer> root, List<Tree<Integer>> subtreePath) {
  192.         subtreePath.add(root);
  193.  
  194.         for (Tree<Integer> child : root.children) {
  195.             getAllChildren(child, subtreePath);
  196.         }
  197.     }
  198.  
  199.     private static int getSubtreeRootWithSum(Tree<Integer> current,
  200.                                              int currentSum, int targetSum,
  201.                                              List<Tree<Integer>> result) {
  202.         if (current == null) {
  203.             return 0;
  204.         }
  205.  
  206.         currentSum = current.value;
  207.  
  208.         for (Tree<Integer> child : current.children) {
  209.             currentSum += getSubtreeRootWithSum(child, currentSum, targetSum, result);
  210.         }
  211.  
  212.         if (currentSum == targetSum) {
  213.             result.add(current);
  214.         }
  215.  
  216.         return currentSum;
  217.     }
  218.  
  219.     public static void main(String[] args) throws IOException {
  220.         ReadTree();
  221.  
  222.         int sum = Integer.parseInt(bufferedReader.readLine());
  223.  
  224.  
  225.         List<List<Tree<Integer>>> treesWithSum = getTreesWithSum(sum);
  226.  
  227.         List<String> resultValues = treesWithSum.stream()
  228.                 .map(list -> String.join(" ",
  229.                         list.stream()
  230.                                 .map(x -> x.value + "")
  231.                                 .collect(Collectors.toList())))
  232.                 .collect(Collectors.toList());
  233.  
  234.         System.out.printf("Subtrees of sum %d:%n%s", sum,
  235.                 String.join(System.lineSeparator(), resultValues));
  236.     }
  237.  
  238. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement