zoukankan      html  css  js  c++  java
  • POJ2054 Color a Tree 贪心

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

    假如现在有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
    ",ans);
    65     }
    66     return 0;
    67 }
    View Code
  • 相关阅读:
    [团队项目] Scrum 项目 3.0 SCRUM 流程的步骤2: Spring 计划
    《构建之法》第6-7章读后感
    【操作系统】实验二 作业调度模拟程序
    团队项目2.0软件改进分析MathAPP
    团队项目
    结对编程2.0
    电影(网剧))项目
    实验0 了解和熟悉操作系统
    复利计算
    学习进度条
  • 原文地址:https://www.cnblogs.com/MyGirlfriends/p/9317040.html
Copyright © 2011-2022 走看看