115. 给树染色

 

 

继续看yan老哥的视频    还是一边看yan老哥视频一边敲代码 总感觉自己现在还不具备单独过提高组+题目的能力  写代码5分钟调试半小时   不是这错就是那错  ;这是个greedy题 而且要找出一个顺序        ;那么我们假设子节点b其父节点a    

以及一个八杆子打不着的节点c      ;   如果先选b,a  那么  cost为  a+2b+3c;   

如果先选c 则为  c+2a+3b;  结果是看c 和 (a+b)/2的关系 

那么推广到一般情况    结果就是看那一坨节点的平均值  ;    所以我们不停的找出非根节点的最大节点  ;然后将其并入父节点  ,最终根节点就是答案;   

做法 ;

1   begin:f[i]=i;  最初各自为一组  

2  接下来每次会将两组点合并,将其中一组点接在另一组点的后面    

 

 

 代码 

#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <string>
#include <bitset>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <list>
#include <map>
#include <set>
#include<iomanip>
#include <bits/stdc++.h>
/***************************************/
#define  ll  long long
#define int64 __int64
#define PI 3.1415927
#define INF 99999
#define MAXN 1000010
using namespace std;

 struct node
 {
     int father, size ,sum;//父节点     子树个数  权值和
     double avg;
 }nodes[1010];     int n,root;

int find()//求当前这个点权值的非根节点
{
 double avg=0;  int ans=-1;


 for(int i=1;i<=n;i++)
 {
       if(i!=root&&nodes[i].avg>avg)//根节点无法往上和并
       {
          avg=nodes[i].avg;
          ans=i;
       }
 }

    return ans;
}

  int main()

{

       cin>>n>>root; int res=0;
       for(int i=1;i<=n;i++)
       {    cin>>nodes[i].sum;
           nodes[i].avg = nodes[i].sum;
        nodes[i].size = 1;
        res += nodes[i].sum;
       }
         int a,b;
         for(int i=0;i<n-1;i++)
         {
             cin>>a>>b;
nodes[b].father=a ;

         }
         for(int i=0;i<n-1;i++)
         {
              int ver=find();
              int father_baba =nodes[ver ].father;
              res+= nodes[ver].sum*nodes[father_baba].size;  //更新答案
              nodes [ver].avg=-1;//已经被遍历
             for(int  j=1 ;j<=n;j++)//合并   删边 连结点
             {
                  if(nodes[j].father== ver)
                  {
                  nodes[j].father =father_baba ;

             } 
             }
 nodes[father_baba].sum+=nodes[ver].sum;
             nodes[father_baba].size+=nodes[ver].size;
               nodes[father_baba].avg=(double)nodes[father_baba].sum/nodes[father_baba].size ;

         }  cout<<res<<endl;

    return 0;
}

  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值