码迷,mamicode.com
首页 > 其他好文 > 详细

POJ2054 Color a Tree 贪心

时间:2018-07-16 13:57:11      阅读:207      评论:0      收藏:0      [点我收藏+]

标签:mes   names   span   using   size   clear   amp   hid   hide   

容易知道,除了根节点之外,下面的儿子节点如果是全树权值最大的点一定会在父亲节点染色之后被染色。

假如现在有x,y,z三个节点,现在知道x和y的染色是连续的。

那么先染x,y再染z的代价是x+2y+3z

如果先z后x和y那么代价是z+2x+3y

都加上(z-y)后再除以2,就是(x+y)/2+2z和z+(x+y)

也就是(x+y)/2和z谁先染色的代价

于是同理可知多个点的合并节点等价代价为sum/点数

然后不断合并就好了

技术分享图片
 1 /* ***********************************************
 2 Author        :BPM136
 3 Created Time  :2018/7/16 11:36:59
 4 File Name     :2054.cpp
 5 ************************************************ */
 6 
 7 #include<iostream>
 8 #include<cstdio>
 9 #include<algorithm>
10 #include<cstdlib>
11 #include<cmath>
12 #include<cstring>
13 #include<vector>
14 using namespace std;
15 
16 typedef long long ll;
17 typedef vector<int> VI;
18 
19 const int N = 1005;
20 
21 int c[N],a[N];
22 int fa[N];
23 int n,root;
24 VI b[N];
25 bool vis[N];
26 
27 int main() {
28     while(scanf("%d%d",&n,&root)!=EOF) {
29         if(n==0 && root==0) return 0;
30         for(int i=1;i<=n;i++) {
31             scanf("%d",&c[i]);
32             a[i]=c[i];
33         }
34         for(int i=1;i<n;i++) {
35             int p,f;
36             scanf("%d%d",&f,&p);
37             fa[p]=f;
38         }
39         for(int i=1;i<=n;i++) {
40             b[i].clear();
41             b[i].push_back(i);
42         }
43         for(int i=1;i<=n;i++) vis[i]=0;
44         vis[root]=1;
45         for(int o=1;o<n;o++) {
46             int v=0;
47             double mx=0.0;
48             for(int i=1;i<=n;i++) if(vis[i]==0) {
49                 if(a[i]*1.0/b[i].size()>mx) {
50                     mx=a[i]*1.0/b[i].size();
51                     v=i;
52                 }
53             }
54             int f=fa[v];
55             vis[v]=1;
56             for(int i=0;i<b[v].size();i++) b[f].push_back(b[v][i]);
57             a[f]+=a[v];
58             for(int i=1;i<=n;i++) if(vis[i]==0 && fa[i]==v) {
59                 fa[i]=f;
60             }
61         }
62         ll ans=0;
63         for(int i=0;i<b[root].size();i++) ans+=(long long)(i+1)*c[ b[root][i] ];
64         printf("%lld\n",ans);
65     }
66     return 0;
67 }
View Code

 

POJ2054 Color a Tree 贪心

标签:mes   names   span   using   size   clear   amp   hid   hide   

原文地址:https://www.cnblogs.com/MyGirlfriends/p/9317040.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!