【codeforces 348B】Apple Tree
【题目链接】:http://codeforces.com/problemset/problem/348/B
【题意】
给你一棵树;
叶子节点有权值;
对于非叶子节点;
它的权值是以这个节点为根的子树上的叶子节点的权值的和;
定义一棵树是平衡的,当且仅当,每个节点的所有直系儿子的权值都相等;
问你要使得这棵树平衡,最少需要删除掉多少叶子节点上的权值;
【题解】
在第一个dfs里面求出d[i]和s[i];
设d[i]表示以i为根的子树要平衡的话最少需要多少权值(注意这里不是说最少要删去多少权值,而是最少需要多少权值),对于叶子节点d[i]=1,非叶子节点的话,d[i] = k*lcm(d[j]),j是i的儿子节点,k是i的直系儿子节点个数;
因为只有按照这样的分法,才能保证都能平均地分下来;也就是说如果最后i节点有权值的话,他一定得是d[i]的倍数;
(lcm是最小公倍数);
s[i]是以i为根的子树里面叶子节点的权值和;
在第二个dfs里面算需要删掉多少;
对于i节点;
先求出t = d[i]/k;这里k同样是i奇点的直系儿子节点的个数;
这样,我们就先算出了,每个儿子节点的权值都应该是t的倍数才对;
然后我们求出所有儿子节点j里面,s的值最小的s[j]=mis;
然后让所有的s[j]变成最小的t的倍数,也即t = (mis/t) * t
然后∑s[j] - t*k 就是需要扣除掉的;
注意这里之后要更新每个儿子节点的s值,同时更新i节点的s值;
注意为根节点的时候,len和非和节点的时候的len…,根节点就算len=1也得继续往下做,不能直接退出。。。所以注意叶子节点的判断。
【Number Of WA】
1
【反思】
这道题,注意到每个节点都有一个最小的平衡权值,且注意到都得是这个最小平衡权值的整数倍是关键。
【完整代码】
#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define ms(x,y) memset(x,y,sizeof x)
#define Open() freopen("F:\\rush.txt","r",stdin)
#define Close() ios::sync_with_stdio(0)
typedef pair<int,int> pii;
typedef pair<LL,LL> pll;
const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);
const int N = 1e5+100;
const LL oo = 1e18;
LL d[N],s[N],a[N],sum,ans;
int n;
vector <int> G[N];
LL lcm(LL x,LL y){
return (x/__gcd(x,y))*y;
}
void out(){
cout << sum << endl;
exit(0);
}
void dfs1(int x,int fa){
d[x] = 1,s[x] = a[x];
if (G[x].size()==1 && x!=1){
return;
}
int len = G[x].size();
d[x] = 1;
rep1(i,0,len-1){
int y = G[x][i];
if (y==fa) continue;
dfs1(y,x);
d[x] = lcm(d[x],d[y]);
if (d[x]>sum) out();
s[x] += s[y];
}
if (x==1)
d[x] = d[x]*len;
else
d[x] = d[x]*(len-1);
}
void dfs2(int x,int fa){
int len = G[x].size();
if (len==1 && x!=1) return;
LL mis = oo,temp = 0;
rep1(i,0,len-1){
int y = G[x][i];
if (y == fa) continue;
dfs2(y,x);
mis = min(mis,s[y]);
temp+=s[y];
}
LL t;
if (x==1)
t = d[x]/len;
else
t = d[x]/(len-1);
t = (mis/t)*t;
if (x==1)
ans += temp-t*len;
else
ans += temp-t*(len-1);
s[x] = a[x];
rep1(i,0,len-1){
int y = G[x][i];
if (y==fa) continue;
s[y] = t;
s[x]+=s[y];
}
}
int main(){
//Open();
Close();
cin >> n;
rep1(i,1,n){
cin >> a[i];
sum += a[i];
}
rep1(i,1,n-1){
int x,y;
cin >> x >> y;
G[x].pb(y);
G[y].pb(x);
}
dfs1(1,-1);
dfs2(1,-1);
cout << ans << endl;
return 0;
}
【codeforces 348B】Apple Tree的更多相关文章
- 【POJ 2486】 Apple Tree(树型dp)
[POJ 2486] Apple Tree(树型dp) Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 8981 Acce ...
- 【POJ 2486】 Apple Tree (树形DP)
Apple Tree Description Wshxzt is a lovely girl. She likes apple very much. One day HX takes her to a ...
- 【13.91%】【codeforces 593D】Happy Tree Party
time limit per test3 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 【codeforces 723F】st-Spanning Tree
[题目链接]:http://codeforces.com/contest/723/problem/F [题意] 给你一张图; 让你选择n-1条边; 使得这张图成为一颗树(生成树); 同时s的度数不超过 ...
- 【树形dp】Apple Tree
[poj2486]Apple Tree Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10800 Accepted: 3 ...
- 【Codeforces 715C】Digit Tree(点分治)
Description 程序员 ZS 有一棵树,它可以表示为 \(n\) 个顶点的无向连通图,顶点编号从 \(0\) 到 \(n-1\),它们之间有 \(n-1\) 条边.每条边上都有一个非零的数字. ...
- Codeforces 348B:Apple Tree(DFS+LCM+思维)
http://codeforces.com/contest/348/problem/B 题意:给一棵树,每个叶子结点有w[i]个苹果,每个子树的苹果数量为该子树所有叶子结点苹果数量之和,要使得每个结点 ...
- 【POJ 3321】Apple Tree
有n个节点以1为根节点的树,给你树的边关系u-v,一开始每个节点都有一个苹果,接下来有两种操作,C x改变节点x的苹果状态,Q x查询x为根的树的所有苹果个数. 求出树的dfs序,st[i]保存i ...
- 【codeforces 415D】Mashmokh and ACM(普通dp)
[codeforces 415D]Mashmokh and ACM 题意:美丽数列定义:对于数列中的每一个i都满足:arr[i+1]%arr[i]==0 输入n,k(1<=n,k<=200 ...
随机推荐
- FreeCodeCamp初级算法部分学习
Reverse a String 翻转字符串 先把字符串转化成数组,再借助数组的reverse方法翻转数组顺序,最后把数组转化成字符串. 你的结果必须得是一个字符串 当你完成不了挑战的时候,记得开大招 ...
- 用Arcade表达式添加标签
Arcade表达式是轻量级的脚本语言,我们可以通过全局变量$feature获取要素属性.比如说,要为城市添加标签,利用CITY_NAME列,我们可以编写语句:$feature.CITY_NAME.Ar ...
- Wepy--小程序自定义底部tabBar
PS后续: 说来惭愧, 没想到这篇文章浏览的人有点多. 说实话写的挺乱的. 并且自定义tabbar还有闪屏的问题. 因为有好几位道友都问了这个问题, 其中一位因为项目很急,所以就研究了一下(也是借鉴 ...
- [HDU1195]Open the Lock
题目大意:给你一个4位数的初始状态(只包含1~9),要求你变化成另一个4位数. 变化规则为:每次可给任意一位加1或减1(1减1变为9,9加1变为1),或交换相邻两个数位上的数字(第一位和最后一位不相邻 ...
- # quill-image-extend-module :实现vue-quill-editor图片上传,复制粘贴,拖拽
改造vue-quill-editor: 结合element-ui上传图片到服务器 quill-image-extend-module vue-quill-editor的增强模块, 功能: 提供图片上传 ...
- Qt Designer设计 UI 文件并调用
本文介绍的是Qt Designer设计 UI 文件并调用,在坛子里逛了一圈,关于UI方面的好像不怎多,本篇给大家分享一下. AD: 2013云计算架构师峰会超低价抢票中 Qt Designer设计 U ...
- POJ 3904
第一道莫比乌斯反演的题. 建议参看http://www.isnowfy.com/mobius-inversion/ 摘其中部分 证明的话感觉写起来会比较诡异,大家意会吧说一下这个经典题目:令R(M,N ...
- POJ 1942
开始时竟然用了分情况讨论. 仔细思考一下,哈哈,发现不过是多重集合的组合数而已. #include <iostream> #include <cstdio> #include ...
- Android动态加载字节码
概述 面对App业务逻辑的频繁变更,如果每一次改变都对App进行一次升级,会降低App的用户体验,那么App进行模块化升级(这里与增量升级是不同的)是很好的解决方案,让用户在完全无感觉的情况下改变Ap ...
- 四旋翼飞行器Quadrotor飞控之 PID调节(參考APM程序)
做四轴也有一段时间了.近期一直在做PID方面的工作. 如今四轴基本能够实现室内比較稳定的飞行,操控手感也能够接受.稍后上试飞视频.在此把一些PID方面的经验总结总结和大家分享一下. 首先介绍一下大概的 ...