zoukankan      html  css  js  c++  java
  • Color a tree

    Solution

    众所周知这是一道dl贪心

    Step 1

    如果没有先后染色的顺序让你去染色,你肯定会先把最大的节点先染了,但是如果有了限制,类似的,就会把子节点中最大的点先染了,所以两个操作会是连续的。

    所以假设待染色的点分别为 x,y,z ,其中 x,y 已知是连续染色,则只有两种染法

    1.x+2y+3z1.x+2y+3z 先染 x,y ,再染 z

    2.z+2x+3y2.z+2x+3y 先染 z ,再染 x,y

    比较两数大小, 1-2=-x-y+2z

    也就是比较

    (x+y)/2 

    也就启发我们运用平均值作为性价比,每次扫描一遍求出最大性价比进行染色,将这一个点放在父亲节点中最后一个点之后马上染色,直到最后将整棵树缩成一个点,得到最终答案

    Step 2

    #include<bits/stdc++.h>
    using namespace std;
    int n,r,ans;
    struct node{int c,fa,t;double w;}num[1005];
    int find(){//求出最大性价比
        int mbi;
        double maxn=0;
        for(int i=1;i<=n;i++)
         if(i!=r&&num[i].w>maxn)
          maxn=num[i].w,mbi=i;
        return mbi;
    } 
    int main(){
        while(scanf("%d %d",&n,&r)&&n&&r){
            ans=0;
            for(int i=1;i<=n;i++)scanf("%d",&num[i].c),ans+=num[i].c,num[i].t=1,num[i].fa=0,num[i].w=num[i].c;//预处理清空
            for(int i=1,a,b;i<n;i++)scanf("%d %d",&a,&b),num[b].fa=a;
            for(int i=1;i<n;i++){
                int tmp=find();
                num[tmp].w=0;
                int f=num[tmp].fa;
                ans+=num[tmp].c*num[f].t;//合并性价比最大的节点,在父亲的节点之后紧跟着被染色
                for(int j=1;j<=n;j++)
                 if(num[j].fa==tmp)
                  num[j].fa=f;//合并
                num[f].t+=num[tmp].t;//更新父亲节点
                num[f].c+=num[tmp].c;
                num[f].w=(double)(num[f].c)/num[f].t;
            }
            printf("%d
    ",ans);//输出
        }
    }
  • 相关阅读:
    在SQLite中使用索引优化查询速度
    SQLite支持的SQL数据操作
    left (outer) join , right (outer) join, full (outer) join, (inner) join, cross join 区别
    深入理解Android内存管理原理(六)
    Merge Sorted Array
    Sort Colors
    Construct Binary Tree from Preorder and Inorder Traversal
    Binary Tree Postorder Traversal
    Symmetric Tree
    Rotate Image
  • 原文地址:https://www.cnblogs.com/coder-cjh/p/11581375.html
Copyright © 2011-2022 走看看