You are given a tree consisting of 𝑛n vertices. A tree is a connected undirected graph with 𝑛−1n−1 edges. Each vertex 𝑣v of this tree has a color assigned to it (𝑎𝑣=1av=1 if the vertex 𝑣v is white and 00 if the vertex 𝑣v is black).
You have to solve the following problem for each vertex 𝑣v: what is the maximum difference between the number of white and the number of black vertices you can obtain if you choose some subtree of the given tree that contains the vertex 𝑣v? The subtree of the tree is the connected subgraph of the given tree. More formally, if you choose the subtree that contains 𝑐𝑛𝑡𝑤cntw white vertices and 𝑐𝑛𝑡𝑏cntb black vertices, you have to maximize 𝑐𝑛𝑡𝑤−𝑐𝑛𝑡𝑏cntw−cntb.
Input
The first line of the input contains one integer 𝑛n (2≤𝑛≤2⋅1052≤n≤2⋅105) — the number of vertices in the tree.
The second line of the input contains 𝑛n integers 𝑎1,𝑎2,…,𝑎𝑛a1,a2,…,an (0≤𝑎𝑖≤10≤ai≤1), where 𝑎𝑖ai is the color of the 𝑖i-th vertex.
Each of the next 𝑛−1n−1 lines describes an edge of the tree. Edge 𝑖i is denoted by two integers 𝑢𝑖ui and 𝑣𝑖vi, the labels of vertices it connects (1≤𝑢𝑖,𝑣𝑖≤𝑛,𝑢𝑖≠𝑣𝑖(1≤ui,vi≤n,ui≠vi).
It is guaranteed that the given edges form a tree.
Output
Print 𝑛n integers 𝑟𝑒𝑠1,𝑟𝑒𝑠2,…,𝑟𝑒𝑠𝑛res1,res2,…,resn, where 𝑟𝑒𝑠𝑖resi is the maximum possible difference between the number of white and black vertices in some subtree that contains the vertex 𝑖i.
Examples
input
Copy
9
0 1 1 1 0 0 0 0 1
1 2
1 3
3 4
3 5
2 6
4 7
6 8
5 9
output
2 2 2 2 2 1 1 0 2
input
4
0 0 1 0
1 2
1 3
1 4
output
0 -1 1 -1
#include <bits/stdc++.h>
using namespace std;
const int MAX = 2e5 + 10;
vector<int> e[MAX];
int dp[MAX];
void dfs1(int x, int f) {
for(auto v: e[x]) {
if(v == f) continue;
dfs1(v, x);
dp[x] += max(0, dp[v]);
}
}
void dfs2(int x, int f) {
for(auto v: e[x]) {
if(v == f) continue;
dp[v] += max(0, dp[x] - max(0, dp[v]));
dfs2(v, x);
}
}
int main() {
int n;
cin >> n;
for(int i = 1, x; i <= n; i++) {
cin >> x;
dp[i] = (x == 0 ? -1 : 1);
}
for(int i = 1, x, y; i < n; i++) {
cin >> x >> y;
e[x].push_back(y);
e[y].push_back(x);
}
dfs1(1, 0);
dfs2(1, 0);
for(int i = 1; i <= n; i++) {
cout << dp[i] << " \n"[i == n];
}
}