cf202-div 1-B - Apple Tree:搜索,数论,树的遍历
2 seconds
256 megabytes
standard input
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.
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.
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.
6
0 0 12 13 5 6
1 2
1 3
1 4
2 5
2 6
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:搜索,数论,树的遍历的更多相关文章
- [poj3321]Apple Tree(dfs序+树状数组)
Apple Tree Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 26762 Accepted: 7947 Descr ...
- POJ 题目3321 Apple Tree(线段树)
Apple Tree Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 21566 Accepted: 6548 Descr ...
- 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 ...
- 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 ...
- 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 ...
- POJ 3321 Apple Tree DFS序 + 树状数组
多次修改一棵树节点的值,或者询问当前这个节点的子树所有节点权值总和. 首先预处理出DFS序L[i]和R[i] 把问题转化为区间查询总和问题.单点修改,区间查询,树状数组即可. 注意修改的时候也要按照d ...
- 1020. Tree Traversals (25) ——树的遍历
//题目 通过后续遍历 中序遍历 得出一棵树 ,然后按树的层次遍历打印 PS:以前对于这种用指针的题目是比较头痛的,现在做了一些链表操作后,感觉也不难 先通过后续中序建一棵树,然后通过BFS遍历这棵树 ...
- ACM学习历程——POJ3321 Apple Tree(搜索,线段树)
Description There is an apple tree outside of kaka's house. Every autumn, a lot of apples will ...
- POJ3321 Apple Tree (树状数组)
Apple Tree Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 16180 Accepted: 4836 Descr ...
随机推荐
- Android Spinner列表选择框
Spinner Spinner是一个下拉列表,通常用于选择一系列可选择的列表项,它可以使用适配器,也可以直接设置数组源. 1.直接设置数组源 在res/values/strings.xml中设置数组源 ...
- Android -- getSystemService
Android的后台运行在很多service,它们在系统启动时被SystemServer开启,支持系统的正常工作,比如MountService监听是否有SD卡安装及移除,ClipboardServic ...
- svn不提交user文件
http://godera.blog.163.com/blog/static/215023060201312011112966/
- hdu 2201
题意: 一共有n个人,m表示第m个人,然后问你第i个人不做到m号位置的概率,最后相乘.... 水题(注意下格式输出) AC代码: #include <iostream> using nam ...
- sessionstorage,localstorage和cookie之间的区别
sessionStorage 和 localStorage 是HTML5 Web Storage API 提供的,可以方便的在web请求之间保存数据.有了本地数据,就可以避免数据在浏览器和服务器间不必 ...
- 从BufferedImage到InputStream,实现绘图后进行下载(生成二维码图片并下载)
@SuppressWarnings("resource") public void download() throws Exception{ String filename = & ...
- Error: theForm.submit is not a function !!
theForm.submit is not a function 调试了半天,才发现范了低级错误. 页面中有一个按钮ID 是 submit 而引发的错误. 引出的问题是页面上的元素命名范围不能是 wi ...
- Sql 中常用日期转换Convert(Datetime)
CONVERT(data_type,expression[,style]) convert(varchar(10),字段名,转换格式) 说明:此样式一般在时间类型(datetime,smalldate ...
- Fiddler 网页采集抓包利器
最近这段时间,网页采集方面的工作做得比较多.用curl技术开发了一个微信文章聚合类产品,把抓取到的数据转换成json格式,并在android端调用json数据接口加以显示:基于weiphp做了一个掌上 ...
- 直接拨号、将电话号码传入拨号程序、调用拨号程序、调用系统浏览器浏览网页、调用系统程序查看联系人、显示系统设置界面和显示Wi-Fi设置界面代码
直接拨号.将电话号码传入拨号程序.调用拨号程序.调用系统浏览器浏览网页.调用系统程序查看联系人.显示系统设置界面和显示Wi-Fi设置界面代码 拨打号码的代码如下: Intent callIntent= ...