zoukankan      html  css  js  c++  java
  • CF1092F Tree with Maximum Cost(dfs+dp)

    果然我已经菜到被(div3)的题虐哭了

    qwq

    首先看到这个题,一个比较显然的想法就是先从1号点开始(dfs)一遍,然后通过一些奇怪的方式,再(dfs)一遍得到其他点的贡献。

    那么具体应该这么做呢。
    首先,我们维护两个数组(dis[i])表示(i)到1的距离,(sum[i])表示(i)的子树中的(val)的和。

    然后我们考虑,如果从(fa[x])移动到(x),相当于(x)的子树内的(dis)都要减一,对(ans)的贡献是(-sum[x]),然后(x)的子树外面的所有的点的(dis)要加一,对(ans)的贡献是(sum[1]-sum[x])

    那么我们只需要两遍(dfs),第二遍(dfs),一边(dfs)一边更新(ans)就好。

    #include<bits/stdc++.h>
    #define mk make_pair
    #define pb push_back
    #define ll long long
    #define int long long
    
    using namespace std;
    
    inline int read()
    {
      int x=0,f=1;char ch=getchar();
      while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
      while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
      return x*f;
    }
    
    const int maxn = 4e5+1e2;
    const int maxm = 2*maxn;
    
    int point[maxn],nxt[maxm],to[maxm];
    int dis[maxn],sum[maxn];
    int ans;
    int n,m,cnt;
    int tmp;
    int val[maxn];
    
    void addedge(int x,int y)
    {
        nxt[++cnt]=point[x];
        to[cnt]=y;
        point[x]=cnt;
    } 
    
    void dfs(int x,int fa,int dep)
    {
        sum[x]=val[x];
        dis[x]=dep;
        for (int i=point[x];i;i=nxt[i])
        {
            int p = to[i];
            if(p==fa) continue;
            dfs(p,x,dep+1);
            sum[x]+=sum[p];
        }
    }
    
    void solve(int x,int fa,int now)
    {
        ans=max(ans,now);
        for (int i=point[x];i;i=nxt[i])
        {
            int p=to[i];
            if (p==fa) continue;
            solve(p,x,now+sum[1]-sum[p]-sum[p]); 
        }
    }
    
    signed main()
    {
      n=read();
      for (int i=1;i<=n;i++) val[i]=read();
      for (int i=1;i<n;i++)
      {
      	int x=read(),y=read();
      	addedge(x,y);
      	addedge(y,x);
      }
      dfs(1,0,0);
      for (int i=1;i<=n;i++) tmp=tmp+dis[i]*val[i];
      ans=tmp;
      //cout<<ans<<endl;
      solve(1,0,tmp); 
      cout<<ans;
      return 0;
    }
    
  • 相关阅读:
    Difference Between Arraylist And Vector : Core Java Interview Collection Question
    Man's Best Friend: The Science Behind the Dog and Human Relationship
    我在微软那些事--微软面试
    北美PM活着的攻略
    C#图解教程 第二十一章 命名空间和程序集
    C#图解教程 第二十章 异步编程
    C#图解教程 第十九章 LINQ
    C#图解教程 第十八章 枚举器和迭代器
    C#图解教程 第十七章 泛型
    C#图解教程 第十六章 转换
  • 原文地址:https://www.cnblogs.com/yimmortal/p/10163292.html
Copyright © 2011-2022 走看看