CF1187E Tree Painting 换根DP

CF1187E Tree Painting

换根DP


链接
换根DP
第一次求出\(f[i]\)表示染\(i\)的子树的价值
那么第二次很明显求的\(g[i]\)表示以\(i\)为根的话答案是多少
\(f[i]=size[i]+{\sum_{s\in son[i]}f[s]}\)
\(g[i]=g[fa]-siz[i]+(n-siz[i])\)


#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=2*1e5+10;
int n,f[maxn],siz[maxn],g[maxn];
vector<int> G[maxn];
void dfs(int x,int fa){
    siz[x]=1;
    for(unsigned int i=0;i<G[x].size();i++){
        int y=G[x][i];
        if(y==fa) continue;
        dfs(y,x);
        siz[x]+=siz[y];
        f[x]+=f[y];
    }
    f[x]+=siz[x];
}
void dfs2(int x,int fa){
    for(unsigned int i=0;i<G[x].size();i++){
        int y=G[x][i];
        if(y==fa) continue;
        g[y]=g[x]-siz[y]+(n-siz[y]);
        dfs2(y,x);
    }
}
signed main()
{
    scanf("%lld",&n);
    for(int x,y,i=1;i<n;i++){
        scanf("%lld%lld",&x,&y);G[x].push_back(y);G[y].push_back(x);
    }
    dfs(1,0);
    g[1]=f[1];
    dfs2(1,0);
    int ans=0;
    for(int i=1;i<=n;i++) ans=max(ans,g[i]);
    printf("%lld\n",ans);
    return 0;
}
posted @ 2019-10-31 10:38  ChrisKKK  阅读(132)  评论(0编辑  收藏  举报