Color a tree(均值
Posted hhyx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Color a tree(均值相关的知识,希望对你有一定的参考价值。
# 题意
一个具有n个节点的树,每个节点有一个权值,把所有的节点染色,染色的规则是根节点可以随时被染色,
其他节点必须父节点被染色才能被染色,每次染色的代价为T*A[ i ] ,T记录当前是第几个被染色的
# 题解
错误的贪心:在每一个子树的子节点中选择值最大的,
构造一个极端:让一个权值很小的子树根下面子节点权值极大
一个正确的性质:树中除了根外权最大的点,一定会在其父节点被染色后立即染色
即树中节点权值最大的点和其父节点的染色是绑定的,将这两个合并,合并后的新店的权值是二者平均值
即给x,y,z三点染色,其中x,y是绑定的,x是父节点,有两种可能
1)先染x,y后z,代价 x+2y+3z
2)先z后x,y,代价z+2x+3y
若 x+2y+3z < z+2x+3y 化简后得到
z < (x+y)/2,即先选大的
所以可以用他们的均值代替其原来的值
不断的进行合并,将当前等效权值最大的点排在其父节点最后
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define ld long double 4 #define fi first 5 #define se second 6 #define pii pair<int,int> 7 using namespace std; 8 const int N=1010; 9 struct node{ 10 int val,sz,fa; 11 double avg; 12 }a[N]; 13 int n,root; 14 int find(){ 15 double avg=-1; 16 int res; 17 for(int i = 1; i <= n; i++){ 18 if(i != root && avg < a[i].avg){ 19 avg=a[i].avg; 20 res=i; 21 } 22 } 23 return res; 24 } 25 int main() { 26 ios::sync_with_stdio(0); 27 cin.tie(0); 28 cout.tie(); 29 cin>>n>>root; 30 int ans=0; 31 for(int i = 1; i <= n; i++) { 32 cin >> a[i].val; 33 a[i].sz = 1; 34 a[i].avg = a[i].val; 35 ans+=a[i].val; 36 } 37 38 for(int i = 0; i < n-1; i++){ 39 int x,y; 40 cin>>x>>y; 41 a[y].fa = x; 42 } 43 for(int i = 0; i < n-1; i++){ 44 int p = find(); 45 int pa=a[p].fa; 46 ans+=a[p].val*a[pa].sz; 47 a[p].avg=-1; 48 49 for(int j=1;j<=n;j++) 50 if(a[j].fa==p) 51 a[j].fa=pa; 52 a[pa].val+=a[p].val; 53 a[pa].sz+=a[p].sz; 54 a[pa].avg=(double)a[pa].val/a[pa].sz; 55 } 56 cout<<ans; 57 }
以上是关于Color a tree(均值的主要内容,如果未能解决你的问题,请参考以下文章