【题目链接】: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的更多相关文章

  1. 【POJ 2486】 Apple Tree(树型dp)

    [POJ 2486] Apple Tree(树型dp) Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8981   Acce ...

  2. 【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 ...

  3. 【13.91%】【codeforces 593D】Happy Tree Party

    time limit per test3 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  4. 【codeforces 723F】st-Spanning Tree

    [题目链接]:http://codeforces.com/contest/723/problem/F [题意] 给你一张图; 让你选择n-1条边; 使得这张图成为一颗树(生成树); 同时s的度数不超过 ...

  5. 【树形dp】Apple Tree

    [poj2486]Apple Tree Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10800   Accepted: 3 ...

  6. 【Codeforces 715C】Digit Tree(点分治)

    Description 程序员 ZS 有一棵树,它可以表示为 \(n\) 个顶点的无向连通图,顶点编号从 \(0\) 到 \(n-1\),它们之间有 \(n-1\) 条边.每条边上都有一个非零的数字. ...

  7. Codeforces 348B:Apple Tree(DFS+LCM+思维)

    http://codeforces.com/contest/348/problem/B 题意:给一棵树,每个叶子结点有w[i]个苹果,每个子树的苹果数量为该子树所有叶子结点苹果数量之和,要使得每个结点 ...

  8. 【POJ 3321】Apple Tree

    有n个节点以1为根节点的树,给你树的边关系u-v,一开始每个节点都有一个苹果,接下来有两种操作,C x改变节点x的苹果状态,Q x查询x为根的树的所有苹果个数.   求出树的dfs序,st[i]保存i ...

  9. 【codeforces 415D】Mashmokh and ACM(普通dp)

    [codeforces 415D]Mashmokh and ACM 题意:美丽数列定义:对于数列中的每一个i都满足:arr[i+1]%arr[i]==0 输入n,k(1<=n,k<=200 ...

随机推荐

  1. why updating the Real DOM is slow, what is Virtaul DOM, and how updating Virtual DOM increase the performance?

    个人翻译: Updating a DOM is not slow, it is just like updating any JavaScript object; then what exactly ...

  2. [BOI2011]MET-Meteors

    题目:洛谷P3527. 题目大意:n个国家在某星球上建立了m个空间站(一个空间站只属于一个国家),空间站围成一个环.现在知道要下k天陨石,每天都在一个区间内下,每个点都下同样多的(若r>l,则说 ...

  3. [LUOGU]2016 Sam数

    我本来想看看SAM,就看见了这个.. 这道题很容易让人想到数位DP,用\(f[i][j]\)表示考虑到第\(i\)位,最后一位是\(j\)的方案数.看到1e18,直接矩阵快速幂加速,因为它每位转移都是 ...

  4. linux下为firfox安装flash player

    1.去官网下载×.tar.gz包,如:flash_player_npapi_linux.x86_64.tar.gz 2.解压 tar -zxvf flash_player_npapi_linux.x8 ...

  5. 四则运算2(最终版)java+jps+sqlServer

    1,设计思想 (1)在java Resources里建立包和类 (2)在类里面写入方法,其中包括生成算式create()和删除算式delete()用来更新数据库中的题目 (3)Show()方法用来随机 ...

  6. [Python Test] Use pytest fixtures to reduce duplicated code across unit tests

    In this lesson, you will learn how to implement pytest fixtures. Many unit tests have the same resou ...

  7. 17、lambda表达式

    一.简介 lambda表达式允许你通过表达式来代替功能接口,lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块),它还增强了集合 ...

  8. 轻松学习JavaScript十七:JavaScript的BOM学习(二)

    JavaScript计时事件 通过使用JavaScript中的BOM对象中的window对象的两个方法就是setTimeout()方法和claerTimeout()方法,我们 有能力作到在一个设定的时 ...

  9. HTML5图片上传预览

    HTML5实现图片的上传预览,需要使用FileReader对象. FileReader: The FileReader object lets web applications asynchronou ...

  10. node09---中间件

    如果我的的get.post回调函数中,没有next参数,那么就匹配上第一个路由,就不会往下匹配了. 如果想往下匹配的话,那么需要写next() 1app.get("/",funct ...