• [BZOJ3829][Poi2014]FarmCraft 贪心


    这个题应该是很容易想到贪心的,只要可是怎么贪才是科学的呢?
    我们分析一下题干,对于每个边只能一进一出因此,对于树上的一棵子树,我们只要一进子树就必须遍历完,
    因此我们只能进行一遍 dfs() 然后我们发现 dfs() 一遍的时间是一定的,
    然后见每个妹子的时间就在这个时间轴上,
    分析完了,我们说一下要贪什么。
    我们先定义一个概念rest[]就是遍历完这个节点的子树以后我们还要为这个节点所费的时间
    One_Stage :除了1节点,之外每个妹子一见面就杀du
    Two_Stage :我们发现最后的答案是 Max(rest[1],c[1])+2*n-2
    Three_Stage :然后我们考虑怎么找rest[1],
    我们发现每个节点的最优rest[],是(子节点的rest[],减去其在这个子树里又经过的时间),再和(他的c[]减去遍历他的时间)取Max
    这样我们线性一波就结局了

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    #define MAXN 500005
    using namespace std;
    inline int read()
    {
      register int sum=0;
      register char ch=getchar();
      while(ch<'0'||ch>'9')ch=getchar();
      while(ch>='0'&&ch<='9')
      {
        sum=(sum<<1)+(sum<<3)+ch-'0';
        ch=getchar();
      }
      return sum;
    }
    inline int Max(int x,int y)
    {
      return x>y?x:y;
    }
    int a[MAXN],m[MAXN],n,t[MAXN];
    vector<int> Via[MAXN];
    void Dfs_T(int x,int fa)
    {
      register int len=Via[x].size();
      for(register int i=0;i<len;++i)
      if(Via[x][i]!=fa)
      {
        Dfs_T(Via[x][i],x);
        t[x]+=2+t[Via[x][i]];
      }
    }
    inline void Init()
    {
      n=read();
      for(register int i=1;i<=n;i++)a[i]=read();
      for(register int i=1,x,y;i<n;i++)x=read(),y=read(),Via[x].push_back(y),Via[y].push_back(x);
      Dfs_T(1,0);
    }
    int rest[MAXN];
    int comp(const int x,const int y)
    {
      return rest[x]>rest[y];
    }
    inline void Dfs_A(int x,int fa)
    {
      register int len=Via[x].size();
      for(register int i=0;i<len;++i)
      if(Via[x][i]!=fa)Dfs_A(Via[x][i],x);
      sort(Via[x].begin(),Via[x].end(),comp);
      if(x!=1)rest[x]=a[x]-t[x];
      register int now=t[x];
      for(register int i=0;i<len;i++)
      if(Via[x][i]!=fa)
      {
        now-=2+t[Via[x][i]];
        rest[x]=Max(rest[x],rest[Via[x][i]]-now-1);
      }
      if(rest[x]<0)rest[x]=0;
    }
    inline void Work()
    {
      Dfs_A(1,0);
      register int ans=Max(rest[1],a[1])+t[1];
      printf("%d",ans);
    }
    int main()
    {
      Init();
      Work();
      return 0;
    }
  • 相关阅读:
    Spring Boot 2.1.10 学习笔记(2)
    Spring Boot 2.1.10 学习笔记(1)
    Win10 下载与激活 MSDN
    Java JDK 1.8 下载及其版本说明 8u202(最后一个免费版)
    shell函数开发意见优化系统脚本
    php大文件下载支持断点续传
    xunsearch使用笔记
    微信使用的curl方法
    php执行sql语句打印结果
    二维数组排序:array_orderby(php官网评论)
  • 原文地址:https://www.cnblogs.com/TSHugh/p/7267655.html
Copyright © 2020-2023  润新知