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
  • 相关阅读:
    iOS项目之wifi局域网传输文件到iPhone的简单实现
    iOS项目之苹果审核被拒
    iOS项目之模拟请求数据
    nvm-window常用命令
    初探浏览器渲染原理
    node + mongodb 简单实现自己的查询接口
    快速理解_.debounce方法
    tr标签使用hover的box-shadow效果不生效
    一个简单的Node命令行程序:文件浏览
    打造丝般顺滑的 H5 翻页库(传送门)
  • 原文地址:https://www.cnblogs.com/MyGirlfriends/p/9317040.html
Copyright © 2011-2022 走看看