zoukankan      html  css  js  c++  java
  • [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;
    }
  • 相关阅读:
    【转】【VS2008无法启动asp.net development server】的解决
    C#运用技巧(1)
    C# — WinForm 基本控件
    TB 需求分析
    C# 远程连接SQL 2005数据库
    SQL语句的运用
    如何跌倒
    国学堂-梁冬对话张长琳《人体的彩虹》系列
    帝范:中国最伟大帝王的沉思录
    web.xml 配置
  • 原文地址:https://www.cnblogs.com/TSHugh/p/7267655.html
Copyright © 2011-2022 走看看