换根DP好题
题目大意:一棵树,节点有黑有白,从某节点出发,遇黑-1,遇白+1。
问:从每个节点出发,能得到的最大值是多少?
直接换根就好了,第一遍扫的时候,子树为正就算上,
第二遍down的时候 对u->v的边,我们看看v有没有对u做贡献,有的话直接删去它的贡献
看看u剩下的能对v做不做贡献就好了
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+10;
vector<int>g[N];
int ans[N],dp[N];
int n;
int c[N];
int res;
void dfs(int u,int father){
dp[u] = c[u]?1:-1;
for(auto &t:g[u]){
if(t==father)continue;
dfs(t,u);
if(dp[t]>0)dp[u]+=dp[t];
}
}
void down(int u,int father){
for(auto t:g[u]){
if(t==father)continue;
int from = dp[u],to =dp[t];
if(to>0)from-=to;
if(from>0)to+=from;
dp[t] = to;
down(t,u);
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)cin>>c[i];
for(int i=1;i<n;++i){
int a,b;cin>>a>>b;
g[a].push_back(b);
g[b].push_back(a);
}
dfs(1,-1);
down(1,-1);
for(int i=1;i<=n;i++)cout<<dp[i]<<" ";
}