http://codeforces.com/contest/348/problem/B
 
B. Apple Tree
time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

You are given a rooted tree with n vertices. In each leaf vertex there's a single integer — the number of apples in this vertex.

The weight of a subtree is the sum of all numbers in this subtree leaves. For instance, the weight of a subtree that corresponds to some leaf is the number written in the leaf.

A tree is balanced if for every vertex v of the tree all its subtrees, corresponding to the children of vertex v, are of equal weight.

Count the minimum number of apples that you need to remove from the tree (specifically, from some of its leaves) in order to make the tree balanced. Notice that you can always achieve the goal by just removing all apples.

Input

The first line contains integer n (2 ≤ n ≤ 105), showing the number of vertices in the tree. The next line contains n integers a1, a2, ..., an (0 ≤ ai ≤ 108), ai is the number of apples in the vertex number i. The number of apples in non-leaf vertices is guaranteed to be zero.

Then follow n - 1 lines, describing the tree edges. Each line contains a pair of integers xi, yi (1 ≤ xi, yi ≤ n, xi ≠ yi) — the vertices connected by an edge.

The vertices are indexed from 1 to n. Vertex 1 is the root.

Output

Print a single integer — the minimum number of apples to remove in order to make the tree balanced.

Please, do not write the %lld specifier to read or write 64-bit integers in С++. It is preferred to use the sin, cout streams cin, cout or the %I64d specifier.

Sample test(s)
Input
6
0 0 12 13 5 6
1 2
1 3
1 4
2 5
2 6
Output
6

题目大意:有一棵有根树,每个叶子节点上面有一定数量的苹果(非叶子节点上没有苹果),现在要使每一个节点它的各个子树上的苹果总数都相等,问至少需要拿走多少个苹果。

这题跟去年校内PK赛的一道暴力题很像,不过那题是一棵二叉树,范围又比较小,所以直接暴力枚举某叶子节点的值,再一层层的往上考虑就可以了。

而这题不一定是二叉树,而且范围比较大,这时我们可以假设整棵树的苹果总数为x,我们假设根节点有n棵子树,那么分给每棵子树的苹果数为1/n*x,并且x一定是n的倍数(刚开始就是因为没考虑到这种情况WA了几发-_-|||)。

利用递归,将子树的苹果平均分给子树的子树。。。

一直到叶子节点,此时我们可以知道,该叶子节点分到的苹果为x的几分之一(设为k),因此x为k的倍数,并且x/k不大于该叶子的原来的苹果数,根据这个,我们可以得到一个最小的x,最后再求一个不大于x的所有k的公倍数,得解。

另外,为了避免倍数累乘的时候溢出,当发现k>x时,易知只能将所有的苹果都移掉,直接输出即可。


 #include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
using namespace std;
#define MAXN 100010
typedef long long ll;
int n;
int num[MAXN];
vector<int> G[MAXN];
ll x,sum=,lcm=;
ll gcd(ll a,ll b)
{
return b== ? a : gcd(b, a%b);
} void dfs(int cur=, ll div=1LL, int fa=-)
{
if(div>x)
{
cout<<sum;
exit();
return;
}
if(num[cur] || G[cur].size()<= && cur!=) // 是叶子节点
{
x=min(x, num[cur]*div);
lcm=div*lcm/gcd(lcm,div);
return;
}
for(int i=; i<G[cur].size(); i++)
{
if(G[cur][i]!=fa)
dfs(G[cur][i], div*(ll)(G[cur].size()-*(cur!=)),cur);
}
}
int main()
{
//freopen("in.txt","r", stdin); cin>>n;
for(int i=; i<=n; i++)
{
scanf("%d", &num[i]);
sum+=(ll)num[i];
}
x=sum;
for(int i=; i<=n-; i++)
{
int u,v;
scanf("%d %d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
dfs();
cout<<sum-x+x%lcm; return ;
}

cf202-div 1-B - Apple Tree:搜索,数论,树的遍历的更多相关文章

  1. [poj3321]Apple Tree(dfs序+树状数组)

    Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 26762   Accepted: 7947 Descr ...

  2. POJ 题目3321 Apple Tree(线段树)

    Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 21566   Accepted: 6548 Descr ...

  3. Codeforces Round #329 (Div. 2) D. Happy Tree Party LCA/树链剖分

    D. Happy Tree Party     Bogdan has a birthday today and mom gave him a tree consisting of n vertecie ...

  4. Codeforces Round #225 (Div. 1) C. Propagating tree dfs序+树状数组

    C. Propagating tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/383/p ...

  5. Codeforces Round #225 (Div. 1) C. Propagating tree dfs序+ 树状数组或线段树

    C. Propagating tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/383/p ...

  6. POJ 3321 Apple Tree DFS序 + 树状数组

    多次修改一棵树节点的值,或者询问当前这个节点的子树所有节点权值总和. 首先预处理出DFS序L[i]和R[i] 把问题转化为区间查询总和问题.单点修改,区间查询,树状数组即可. 注意修改的时候也要按照d ...

  7. 1020. Tree Traversals (25) ——树的遍历

    //题目 通过后续遍历 中序遍历 得出一棵树 ,然后按树的层次遍历打印 PS:以前对于这种用指针的题目是比较头痛的,现在做了一些链表操作后,感觉也不难 先通过后续中序建一棵树,然后通过BFS遍历这棵树 ...

  8. ACM学习历程——POJ3321 Apple Tree(搜索,线段树)

          Description There is an apple tree outside of kaka's house. Every autumn, a lot of apples will ...

  9. POJ3321 Apple Tree (树状数组)

    Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 16180   Accepted: 4836 Descr ...

随机推荐

  1. Windows下用C语言获取进程cpu使用率,内存使用,IO情况

      #ifndef PROCESS_STAT_H #define PROCESS_STAT_H   #ifdef __cplusplus extern “C” { #endif   typedef l ...

  2. 向量的叉积 POJ 2318 TOYS & POJ 2398 Toy Storage

    POJ 2318: 题目大意:给定一个盒子的左上角和右下角坐标,然后给n条线,可以将盒子分成n+1个部分,再给m个点,问每个区域内有多少各点 这个题用到关键的一步就是向量的叉积,假设一个点m在 由ab ...

  3. IO-序列化 Serializable Parcelable Object

    简介 1.什么是序列化和反序列化 对象的寿命通常随着生成该对象的程序的终止而终止,有时候,可能需要将对象的状态保存下来,在需要时再将对象恢复.我们把对象的这种,能记录自己的状态以便将来再生的能力,叫作 ...

  4. C#判断网站运行状态是否正常

    我使用的是控制台应用程序来监控网站的运行状态,通过判断网站请求头(HEAD)来判断是否运行正常 下面列出几种常见的网站状态码 StatusCode 数字表示 OK 200. OK 指示请求成功,且请求 ...

  5. JY01-KX-01

    复习: 1.a标签跳转 <p id="地址"></p> <a href="#地址"></a> 预习: 1.out ...

  6. java RSA签名

    try{ //1初始化秘钥 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); key ...

  7. 微软分布式缓存 appfabric

    appfabric为微软自家产的分布式缓存解决方案,随dotnet4.0一起发布.目前版本为1.1

  8. Visual Studio 2013如何破解(密钥激活)

    其实有个方法最简单,就是点击“帮助”,选择注册产品,点击打开页面右下边的“使用秘钥注册产品”,输入上述秘钥即可.   在输入密钥界面,输入密钥“BWG7X-J98B3-W34RT-33B3R-JVYW ...

  9. Shell中逻辑判断

    [ 条件1 -a 条件2 ]   当1和2都真时才为真 [ 条件1 -o 条件2 ]   当1和2其中一个为真即为真 [ ! 条件 ]           取反   &&     与 ...

  10. rsync从windows到linux的同步备份

    名称 角色 IP地址 Windows server 2003 服务器 Eth0:192.168.1.1 RHEL5.5 客户端 Eth0:192.168.1.2   一.cwRsyncServer服务 ...