E. Tree Painting 二次扫描换根法

E. Tree Painting

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=2e5+10;
int head[maxn*2],nxt[maxn*2],ver[maxn*2];
int tot=0;
void add(int u,int v)
{
    ver[++tot]=v;
    nxt[tot]=head[u];
    head[u]=tot;
}
ll f[maxn],size[maxn];
int n;
void dfs1(int u,int fa)
{
    size[u]=1;
    for(int i=head[u]; i; i=nxt[i])
    {
        int v=ver[i];
        if(v==fa) continue;
        dfs1(v,u);
        size[u]+=size[v];
    }
    f[1]+=size[u];
}

void dfs2(int u,int fa)
{
    for(int i=head[u]; i; i=nxt[i])
    {
        int v=ver[i];
        if(v==fa) continue;
        f[v]=f[u]+n-2*size[v];
        dfs2(v,u);
    }
}
int main()
{

    scanf("%d",&n);
    for(int i=1; i<=n-1; i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        add(u,v);
        add(v,u);
    }
    dfs1(1,0);
    dfs2(1,0);
    ll ans=-1e18;
    for(int i=1; i<=n; i++)
    {
        ans=max(ans,f[i]);
//        printf("%d ",f[i]);
    }
    printf("%lld",ans);
}
原文地址:https://www.cnblogs.com/dongdong25800/p/11127887.html