题目链接:Cut the tree

题解:题目要求求一条边,去掉这条边后得到的两棵树的节点和差的绝对值最小。

暴力求解会超时。

如果我们可以求出以每个节点为根的子树的节点之和,那么当我们去掉一条边(a,b)的时候,其中的一棵树必是以a或者b为根的子树,那么我们就可以知道生成的两棵树的节点之和了。所以,当我们得到以每个节点为根的子树节点和这个信息后(把这个信息存储在TreeNode的value变量中),通过遍历每个节点(每个节点为根的子树必然为某次cut得到的子树之一,例如下图中,2为根的子树对应切割边(1,2)得到的树,而5为根的子树对应切割边(1,5)得到的树),求出最小的W-2*root.value即为所求(W是所有节点的值得和)。

树节点的数据结构定义如下:

static class TreeNode{
int value;
int number;
ArrayList<TreeNode> children;
public TreeNode(int value,int number){
this.value = value;
this.number = number;
children = new ArrayList<TreeNode>();
}
}

value表示该顶点对应的值,number表示顶点的编号,children表示子节点的列表(这里指表示连接关系,也有可能children里面其实存放了父节点,不过可以用接下来的visited数组避免访问到父节点)。

然后从树的任意一个节点开始dfs,把它的value值依次加上各个child为root的子树节点值,就得到以它为root的子树的节点值得和了。而它的child为root的子树节点和就用递归的方法求。上面说了,每次读入一条边(a,b)的时候,即把b加入到a的children集合里面,也把a加入到b的children集合里面。那么在dfs的时候,怎么知道谁是父节点,谁是子节点呢?就用一个visited数组,因为在dfs过程中,父节点一定先被访问,所以在一个节点的children集合里面,已经被visited过的节点就不是它的子节点了。

最后代码如下:

 import java.util.*;

 public class Solution {
static class TreeNode{
int value;
int number;
ArrayList<TreeNode> children;
public TreeNode(int value,int number){
this.value = value;
this.number = number;
children = new ArrayList<TreeNode>();
}
} private static int dfs(TreeNode root,boolean[] visited){
visited[root.number]=true;
for(TreeNode child:root.children){
if(!visited[child.number]){
root.value += dfs(child, visited);
}
}
return root.value;
} public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
TreeNode[] treeNodes = new TreeNode[n];
int W = 0; for(int i = 0;i < n;i++)
{
int value = in.nextInt();
treeNodes[i]=new TreeNode(value,i);
W += value;
} for(int i = 0;i < n-1;i++){
int a = in.nextInt();
int b = in.nextInt();
treeNodes[a-1].children.add(treeNodes[b-1]);
treeNodes[b-1].children.add(treeNodes[a-1]);
} boolean[] visited = new boolean[n]; dfs(treeNodes[0], visited);
int miniDif = Integer.MAX_VALUE; for(TreeNode t:treeNodes){
miniDif = Math.min(miniDif, Math.abs(W-2*t.value));
} System.out.println(miniDif); }
}

另外要积累的一点是java中nested class和inner class的区别,见stackoverflow上面的详细解答,所以上述代码中第4行要把TreeNode声明为nested class,否则它只能通过类Solution调用。

【HackerRank】Cut the tree的更多相关文章

  1. 【数据结构】B-Tree, B+Tree, B*树介绍 转

    [数据结构]B-Tree, B+Tree, B*树介绍 [摘要] 最近在看Mysql的存储引擎中索引的优化,神马是索引,支持啥索引.全是浮云,目前Mysql的MyISAM和InnoDB都支持B-Tre ...

  2. 【题解】Cut the Sequence(贪心区间覆盖)

    [题解]Cut the Sequence(贪心区间覆盖) POJ - 3017 题意: 给定一大堆线段,问用这些线段覆盖一个连续区间1-x的最小使用线段的数量. 题解 考虑一个这样的贪心: 先按照左端 ...

  3. 【LeetCode】199. Binary Tree Right Side View 解题报告(Python)

    [LeetCode]199. Binary Tree Right Side View 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode.com/probl ...

  4. 【数据结构】B-Tree, B+Tree, B*树介绍

    [摘要] 最近在看Mysql的存储引擎中索引的优化,神马是索引,支持啥索引.全是浮云,目前Mysql的MyISAM和InnoDB都支持B-Tree索引,InnoDB还支持B+Tree索引,Memory ...

  5. 【LeetCode】Balanced Binary Tree 解题报告

    [题目] Given a binary tree, determine if it is height-balanced. For this problem, a height-balanced bi ...

  6. 【LeetCode】145. Binary Tree Postorder Traversal

    Difficulty: Hard  More:[目录]LeetCode Java实现 Description https://leetcode.com/problems/binary-tree-pos ...

  7. 【HackerRank】Utopian tree

    The Utopian tree goes through 2 cycles of growth every year. The first growth cycle of the tree occu ...

  8. 【BZOJ-4353】Play with tree 树链剖分

    4353: Play with tree Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 31  Solved: 19[Submit][Status][ ...

  9. 【leetcode】Binary Search Tree Iterator(middle)

    Implement an iterator over a binary search tree (BST). Your iterator will be initialized with the ro ...

随机推荐

  1. 放苹果(整数划分变形题 水)poj1664

    问题:把M个相同的苹果放在N个相同的盘子里.同意有的盘子空着不放,问共同拥有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法. 例子 : 1 7 3 ---------------8 ...

  2. 使用加密的squid配合stunnel实现HTTP代理

    现在大部分人都是用ssh tunnel来搭建socks5代理,其实这种方式效率并不高,ssh tunnel并不是为了做代理而存在的.一个比较好的方法是加密squid配合stunnel实现http代理. ...

  3. a标签跳转新页面

    var url = $("#email_kong").val();       //url=mail.qq.com url = "http://"+url;   ...

  4. 任何应用程序都可拥有 Web Service 组件。

    任何应用程序都可拥有 Web Service 组件. Web Service 的创建与编程语言的种类无关. 本章节我们将为大家介绍使用 PHP 的 SOAP 扩展来创建 Web Service. SO ...

  5. java中.currentTimeMillis的用法和含义

    用法:可以用法获取当前时间的毫秒数,可以通过毫秒数进行时间比较,时间转化以及时间格式化等.public class SystemTime {public static void main(String ...

  6. HTML 事件的例子:

    HTML 事件的例子: 当用户点击鼠标时 当网页已加载时 当图像已加载时 当鼠标移动到元素上时 当输入字段被改变时 当提交 HTML 表单时 当用户触发按键时

  7. Allegro转换PADS终极篇.....

    allegro转pads终极篇                                                                                      ...

  8. wpf数据绑定更新通知

    类似于这样子的;大致的意思是:一个代码变量,通过改变变量的值,绑定这个变量的这个圆颜色也在变化 就是一种心跳效果 在网上数据触发的感觉不多,废了不少时间,这里做个总结 1:通知 class Notif ...

  9. QQ宠物怀念版H5

    <QQ宠物>相伴十三载 哇!明信片邮到了!!开心ヽ(○^㉨^)ノ♪ 大乐斗Ⅱ 怀念一波...

  10. hdu 4587(割点的应用)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4587 思路:题目的意思很简单,就是删除任意2个节点以及关联的边,求图的最大连通分量数.我们知道删除割点 ...