-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMaximumWhiteSubtree.cpp
More file actions
executable file
·169 lines (126 loc) · 3.89 KB
/
MaximumWhiteSubtree.cpp
File metadata and controls
executable file
·169 lines (126 loc) · 3.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/*
Code Forces #627 F
Maximum White Subtree
time limit per test: 2 seconds
memory limit per test: 256 megabytes
input: standard input
output: standard output
You are given a tree consisting of n vertices. A tree is a connected undirected graph with n−1 edges.
Each vertex v of this tree has a color assigned to it (av=1 if the vertex v is white and 0 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≤n≤2⋅105) — the number of vertices in the tree.
The second line of the input contains n integers a1,a2,…,an (0≤ai≤1), where ai is the color of the i-th vertex.
Each of the next n−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≤ui,vi≤n,ui≠vi).
It is guaranteed that the given edges form a tree.
Output
Print n integers 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
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
Note
The first example is shown below:
The black vertices have bold borders.
In the second example, the best subtree for vertices 2,3 and 4 are vertices 2,3 and 4 correspondingly.
And the best subtree for the vertex 1 is the subtree consisting of vertices 1 and 3.
*/
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;
#define ff first
#define ss second
#define int long long
#define pb push_back
#define mp make_pair
#define pii pair<int,int>
#define vi vector<int>
#define mii map<int,int>
#define pqb priority_queue<int>
#define pqs priority_queue<int,vi,greater<int> >
#define setbits(x) __builtin_popcountll(x)
#define zrobits(x) __builtin_ctzll(x)
#define mod 1000000007
#define inf 1e18
#define ps(x,y) fixed<<setprecision(y)<<x
#define mk(arr,n,type) type *arr=new type[n];
#define w(x) int x; cin>>x; while(x--)
#define pw(b,p) pow(b,p) + 0.1
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> pbds;
void c_p_c()
{
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
}
int n;
int a[200001];
vi adj[200001];
int dp1[200001];
int dp2[200001];
void dfs1(int nd = 1, int pr = 0){
dp1[nd] = a[nd] == 1 ? 1 : -1;
for (auto ch : adj[nd]){
if (ch == pr)
continue;
dfs1(ch, nd);
dp1[nd] += max(0ll, dp1[ch]);
}
}
void dfs2(int nd = 1, int pr = 0){
dp2[nd] = dp1[nd];
if (pr){
int val = dp2[pr] - max(0ll, dp1[nd]);
dp2[nd] += max(0ll, val);
}
for (auto ch : adj[nd]){
if (ch == pr)
continue;
dfs2(ch, nd);
}
}
int32_t main()
{
c_p_c();
cin >> n;
for (int i = 1; i <= n; ++i)
cin >> a[i];
for (int i = 0; i < n - 1; ++i){
int u, v; cin >> u >> v;
adj[u].pb(v);
adj[v].pb(u);
}
dfs1();
dfs2();
for (int i = 1; i <= n; ++i)
cout << dp2[i] << ' ';
return 0;
}