https://codeforces.com/problemset/problem/1324/F
理解样例20分钟,写题10分钟系列
subtree不是子树是子图
树形DP维护sonval[u]表示以1位根,向下的子图能得到的最大值
然后第二遍维护faval,向上的子图能得到的最大值。
#include<bits/stdc++.h>
using namespace std;
const int maxl=2e5+10;
int n;
int a[maxl],ans[maxl];
int sonval[maxl];
bool vis[maxl];
vector<int> e[maxl];
inline void dfs1(int u,int fa)
{
if(a[u]==1)
sonval[u]=1;
else
sonval[u]=-1;
for(int v:e[u])
{
if(v==fa) continue;
dfs1(v,u);
if(sonval[v]>0)
sonval[u]+=sonval[v];
}
}
inline void prework()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
int u,v;
for(int i=1;i<n;i++)
{
scanf("%d%d",&u,&v);
e[u].push_back(v);
e[v].push_back(u);
}
dfs1(1,0);
}
inline void dfs2(int u,int fa,int faval)
{
ans[u]=faval+sonval[u];
for(int v:e[u])
{
if(v==fa) continue;
if(sonval[v]>0)
dfs2(v,u,max(ans[u]-sonval[v],0));
else
dfs2(v,u,max(ans[u],0));
}
}
inline void mainwork()
{
dfs2(1,0,0);
}
inline void print()
{
for(int i=1;i<=n;i++)
printf("%d%c",ans[i],(i==n)?'\n':' ');
}
int main()
{
prework();
mainwork();
print();
return 0;
}