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(均值的主要内容,如果未能解决你的问题,请参考以下文章

HDU - 6241 :Color a Tree(不错的二分)

Color a Tree

HDU 1055 Color a Tree

POJ2054 Color a Tree

poj2054 Color a Tree

UVA - 1205 Color a Tree