【发布时间】:2017-02-18 08:26:09
【问题描述】:
网站上说的问题是
Atul 热衷于图论,现在他正在学习树。他观察到,从给定的树 T 中删除一条边将导致形成两棵独立的树 T1 和 T2。
树 T 的每个顶点都被分配一个正整数。您的任务是删除一条边,以使结果树的 Tree_diff 最小化。 Tree_diff 定义如下:
F(T) = 写在树 T 的每个顶点上的数字之和
Tree_diff(T) = abs(F(T1) - F(T2))
输入格式 第一行将包含一个整数 N,即树中的顶点数。 下一行将包含由单个空格分隔的 N 个整数,即分配给每个顶点的值(其中第一个是树的根)。 接下来的 N-1 行包含一对整数,每行由一个空格分隔,表示树的边缘。 在上面的输入中,顶点的编号是从 1 到 N。
输出格式 包含 Tree_diff 最小值的单行。
Constraints
3≤N≤10^5
1≤ number written on each vertex ≤1001
这里是link的问题
所以我所做的是使用递归 dfs 计算所有子树的 wt 总和,包括最大的树,也就是 = 顶点值的总和。
现在,当我们删除一条边说 u-v,u 是父级时,差异可以简单地计算为:
abs(w[tree[0][u]-1]-(tot-w[tree[0][u]-1]))
在哪里
tree[0][u]=v
tot=total sum of all vertices weights.
w[tree[0][u]-1] = sum of wts of all vertices of subtree rooted at vertex v
F(T1)=(tot-w[tree[0][u]-1])
F(T2)=(w[tree[0][u]-1])
如果不是左孩子,而是我们将拥有的右孩子
tree[1][u]-1]
而不是
tree[0][u]-1]
第一行是tree[][]数组中的左子还是第二行都没有关系,因为结构可能会改变,但答案将保持不变。
这是我的java代码
import java.io.*;
import java.util.*;
public class Dfs {
static int n;
static int [][]tree = new int[2][100000];
static long []wt=new long[100000];
static long []w=new long[100000];
static int []con=new int[100000];
static int root=0;
static long min=Long.MAX_VALUE;
static long tot=0;
public static void main(String[] args)throws IOException
{
/* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution. */
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String []sa;int i,u,v;
n=Integer.parseInt(br.readLine());
sa=br.readLine().split(" ");i=0;
for(String s:sa)
wt[i++]=Long.parseLong(s);
for(i=0;i<n-1;++i)
{
sa=br.readLine().split(" ");
u=Integer.parseInt(sa[0]);
v=Integer.parseInt(sa[1]);
if(i==0)
{
tree[0][u-1]=v;
root=u;
}
else
{
if(con[u-1]==-1)
{
if(tree[0][u-1]==0)
tree[0][u-1]=v;
else tree[1][u-1]=v;
}
else
{
if(tree[0][v-1]==0)
tree[0][v-1]=u;
else tree[1][v-1]=u;
}
}
con[u-1]=-1;
con[v-1]=-1;
}
tot=dfs(root);
w[root-1]=tot;
for(i=0;i<n;++i)
{
if(tree[0][i]!=0)
{
if(min>Math.abs(w[tree[0][i]-1]-(tot-w[tree[0][i]-1])))
min=Math.abs(w[tree[0][i]-1]-(tot-w[tree[0][i]-1]));
}
if(tree[1][i]!=0)
{
if(Math.abs(w[tree[1][i]-1]-(tot-w[tree[1][i]-1]))<min)
min=Math.abs(w[tree[1][i]-1]-(tot-w[tree[1][i]-1]));
}
}
System.out.println(min);
}
static long dfs(int v)
{
long s1=0,s2=0;
if(tree[0][v-1]!=0)
{s1=dfs(tree[0][v-1]);w[tree[0][v-1]-1]=s1;}
if(tree[1][v-1]!=0)
{s2=dfs(tree[1][v-1]);w[tree[1][v-1]-1]=s2;}
return wt[v-1]+s1+s2;
}
}
问题是它对大多数测试用例给出了错误的答案。我哪里出错了?
【问题讨论】:
-
您的代码似乎假定树是二进制的。这真的是给定的吗?
标签: algorithm tree depth-first-search