CF1324 Maximum White Subtree 【換根dp】

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];
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章