Advertisement
T-D-K

Untitled

Feb 1st, 2020
668
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.38 KB | None | 0 0
  1. using System.CodeDom.Compiler;
  2. using System.Collections.Generic;
  3. using System.Collections;
  4. using System.ComponentModel;
  5. using System.Diagnostics.CodeAnalysis;
  6. using System.Globalization;
  7. using System.IO;
  8. using System.Linq;
  9. using System.Reflection;
  10. using System.Runtime.Serialization;
  11. using System.Text.RegularExpressions;
  12. using System.Text;
  13. using System;
  14.  
  15. class Solution {
  16.     class Node {
  17.         public int Index;
  18.         public int Coin;
  19.         public List<int> Child;
  20.         public int Parent;
  21.         public long SumToParent;
  22.         public HashSet<long> Set;
  23.         public Node(int index, int coin) {
  24.             Index = index;
  25.             Coin = coin;
  26.             Child = new List<int>();
  27.             Parent = -1;
  28.             SumToParent = 0;
  29.         }
  30.  
  31.         public override string ToString() {
  32.             return $"I = {Index}, C = {Coin}, S = {SumToParent}, P = {Parent}, Ch = " + string.Join(", ", Child.Select(i => i.ToString()));
  33.         }
  34.     }
  35.  
  36.     class Pair {
  37.         public long Sum;
  38.         public HashSet<long> Set;
  39.         public Pair(long sum, HashSet<long> set) {
  40.             Sum = sum;
  41.             Set = set;
  42.         }
  43.     }
  44.  
  45.     static void PrintTree(IEnumerable<Node> nodes) {
  46.         foreach (var node in nodes) {
  47.             Console.WriteLine(node);
  48.         }
  49.     }
  50.  
  51.     static void PrintTree(IEnumerable<int> indices, List<Node> nodes) {
  52.         foreach (var node in indices) {
  53.             Console.WriteLine(nodes[node]);
  54.         }
  55.     }
  56.  
  57.     // Complete the balancedForest function below.
  58.     static long balancedForest(int[] c, int[][] edges) {
  59.         if (c.Length == 1)
  60.             return -1;
  61.         //Console.WriteLine("*******************************");
  62.         List<Node> nodes = new List<Node>(c.Length);
  63.         long totalSum = 0;
  64.         for (var i = 0; i < c.Length; i++) {
  65.             totalSum += (long)c[i];
  66.             nodes.Add(new Node(i, c[i]));
  67.         }
  68.         foreach (var edge in edges) {
  69.             var x = edge[0] - 1;
  70.             var y = edge[1] - 1;
  71.             nodes[x].Child.Add(y);
  72.             nodes[y].Child.Add(x);
  73.         }
  74.         //PrintTree(nodes);
  75.         HashSet<long> set = new HashSet<long>();
  76.         List<int> levels = new List<int>(c.Length);
  77.         Queue<int> queue = new Queue<int>();
  78.         queue.Enqueue(0);
  79.         levels.Add(0);
  80.         while (queue.Count > 0) {
  81.             var current = nodes[queue.Dequeue()];
  82.             foreach (var child in current.Child) {
  83.                 if (child == current.Parent) {
  84.                     continue;
  85.                 }
  86.                 nodes[child].Parent = current.Index;
  87.                 levels.Add(child);
  88.                 queue.Enqueue(child);
  89.             }
  90.         }        
  91.         //PrintTree(levels, nodes);
  92.         levels.Reverse();
  93.         long ans = long.MaxValue;
  94.         foreach (var node in levels) {
  95.             var current = nodes[node];
  96.             current.Set = new HashSet<long>();
  97.             var childSums = new List<Pair>(current.Child.Count - 1);
  98.             foreach (var child in current.Child) {
  99.                 if (child == current.Parent) {
  100.                     continue;
  101.                 }
  102.                 childSums.Add(new Pair(nodes[child].SumToParent, nodes[child].Set));
  103.                 current.Set.UnionWith(nodes[child].Set);
  104.                 nodes[child].Set = null;
  105.                 current.SumToParent += nodes[child].SumToParent;
  106.             }
  107.             current.SumToParent += current.Coin;
  108.             current.Set.Add(current.SumToParent);
  109.             childSums.Sort((p1, p2) => p1.Sum.CompareTo(p2.Sum));
  110.             childSums.Reverse();
  111.             //Console.WriteLine($"Current = {current}");            
  112.             //Console.WriteLine($"ChildSums : {String.Join(", ", childSums.Select(p => p.Sum))}");
  113.             //Console.WriteLine($"HashSets : {String.Join("; ",
  114.                 //childSums.Select(p => String.Join(", ", p.Set)))}"
  115.             //);
  116.             foreach (var pair in childSums) {
  117.                 var childSum = pair.Sum;
  118.                 var childSet = pair.Set;
  119.                 bool wasAdd = set.Add(childSum);
  120.                 if (!wasAdd && 3 * childSum >= totalSum) {
  121.                     ans = Math.Min(3 * childSum - totalSum, ans);
  122.                     Console.WriteLine($"ans = {ans} <-- 1");
  123.                 }
  124.                 var rem = totalSum - childSum;
  125.                 //Console.WriteLine($"childSum = {childSum}, rem = {rem}");
  126.                 if (childSet.Contains(rem) && rem * 2 >= childSum) {
  127.                     ans = Math.Min(rem * 2 - childSum, ans);
  128.                     //Console.WriteLine($"ans = {ans} <-- 2");
  129.                 }
  130.                 if (rem % 2 == 0 && rem / 2 >= childSum && set.Contains(rem / 2) && !(wasAdd && rem /2 == childSum)) {
  131.                     ans = Math.Min(rem / 2 - childSum, ans);
  132.                     //Console.WriteLine($"ans = {ans} <-- 3");
  133.                 }
  134.                 if (rem < childSum && rem * 2 >= childSum && childSet.Contains(childSum - rem)) {
  135.                     ans = Math.Min(rem * 2 - childSum, ans);
  136.                     //Console.WriteLine($"ans = {ans} <-- 4");
  137.                 }
  138.                 if (rem > childSum && rem < 2 * childSum && set.Contains(rem - childSum) && !childSet.Contains(rem - childSum)) {
  139.                     ans = Math.Min(childSum - (rem - childSum), ans);
  140.                     //Console.WriteLine($"ans = {ans} <-- 5");
  141.                 }
  142.             }
  143.         }
  144.         if (ans == long.MaxValue) {
  145.             ans = -1;
  146.         }
  147.         return ans;
  148.     }
  149.  
  150.     static void Main(string[] args) {
  151.         TextWriter textWriter = new StreamWriter(@System.Environment.GetEnvironmentVariable("OUTPUT_PATH"), true);
  152.  
  153.         int q = Convert.ToInt32(Console.ReadLine());
  154.  
  155.         for (int qItr = 0; qItr < q; qItr++) {
  156.             int n = Convert.ToInt32(Console.ReadLine());
  157.  
  158.             int[] c = Array.ConvertAll(Console.ReadLine().Split(' '), cTemp => Convert.ToInt32(cTemp))
  159.             ;
  160.  
  161.             int[][] edges = new int[n - 1][];
  162.  
  163.             for (int i = 0; i < n - 1; i++) {
  164.                 edges[i] = Array.ConvertAll(Console.ReadLine().Split(' '), edgesTemp => Convert.ToInt32(edgesTemp));
  165.             }
  166.  
  167.             long result = balancedForest(c, edges);
  168.  
  169.             textWriter.WriteLine(result);
  170.         }
  171.  
  172.         textWriter.Flush();
  173.         textWriter.Close();
  174.     }
  175. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement