• CF1098A Sum in the tree(贪心)


    满分做法:

    由题:s[u]<=s[v](u是v的父亲),因为a[i]是非负的。此时点u和他儿子的点权和为:

    (sleft[ u ight] +sum_{vin sonleft( u ight)}{(sleft[ v ight] -sleft[ u ight])})

    (=left( 1-cntleft( u ight) ight) *sleft[ u ight] +sum_{vin sonleft( u ight)}{s}left[ v ight])

    (k=left( 1-cntleft( u ight) ight) le 0)

    所以(s[u])越大点权和越小,最优的(s[u]=min(s[v]));对于s[i]为-1的点,我们先把他赋成较大的数,再通过他们的儿子对他进行赋值。而对于没有被更改的点(也就是偶数层的叶子结点),我们就令他为(0)保证答案最优.

    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<iostream>
    #include<cstdio>
    #include<queue>
    using namespace std;
    typedef long long ll;
    const int maxm=1e5+7;
    int n;
    ll ans;
    int f[maxm];
    ll s[maxm];
    int main()
    {
     scanf("%d",&n);
     for(int i=2;i<=n;i++)
     scanf("%d",&f[i]);
     for(int i=1;i<=n;i++)
     {
      scanf("%lld",&s[i]);
      if(s[i]==-1) s[i]=2147483647;
     }
     for(int i=2;i<=n;i++)
     s[f[i]]=min(s[i],s[f[i]]);
     for(int i=1;i<=n;i++)
     {
      if(s[i]<s[f[i]])
      {
       printf("-1
    ");
       return 0;
      }
      if(s[i]<2147483647) ans+=s[i]-s[f[i]];
     }
     printf("%lld
    ",ans);
     return 0;	
    } 
    
  • 相关阅读:
    知识点拾遗——装饰器
    知识点拾遗——函数部分
    re模块和分组
    re模块进阶
    面向对象总结
    模块总结整理
    项目目录结构
    日志(模块logging)
    位、字节、字符 概念
    socketserver实现并发通讯
  • 原文地址:https://www.cnblogs.com/lihan123/p/11691841.html
Copyright © 2020-2023  润新知