Thinking
-1 rights so little black and white 1 bit to the right, the right to find the maximum point and the subtree.
Set f [i] is the maximum point of the sub-tree comprising i weight points, if the maximum point and the current point weight ratio and the maximum current point right point father small, the current point is updated.
Comparative stupid approach is discussed in the next two cases, the right and the current point is less than 0 or greater than the case where the process is a different point.
If the current ideas tree weights> = 0, and the father's right subtree greater value, should the father subtree merge point to the current point in the sub-tree.
If the current tree idea weights <0, and the father's subtree more white than black, put the point in the subtree father tree merged with the current point.
CODE
#include
<
bits/stdc++.h
>
#define
dbg
(
x
) cout
<< #x
<<
"
=
"
<< x
<< endl
#define
eps
1e
-
8
#define
pi
acos
(
-
1.0
)
using
namespace
std
;
typedef
long
long LL
;
const
int inf
=
0x3f3f3f3f
;
template
<
class
T
>
inline
void
read
(
T
&
res
)
{
char c
;T flag
=
1
;
while
((c
=
getchar
())
<
'
0
'
||c
>
'
9
'
)
if
(c
==
'
-
'
)flag
=-
1
;res
=c
-
'
0
'
;
while
((c
=
getchar
())
>=
'
0
'
&&c
<=
'
9
'
)res
=res
*
10
+c
-
'
0
'
;res
*=flag
;
}
namespace
_buff
{
const
size_t BUFF
=
1
<<
19
;
char
ibuf
[BUFF
],
*ib
= ibuf
,
*ie
= ibuf
;
char
getc
()
{
if
(ib
== ie
)
{
ib
= ibuf
;
ie
= ibuf
+
fread
(ibuf
,
1
, BUFF
, stdin
);
}
return ib
== ie
?
-
1
:
*ib
++
;
}
}
int
qread
()
{
using
namespace
_buff
;
int ret
=
0
;
bool pos
=
true
;
char c
=
getc
();
for
(;
(c
<
'
0
'
|| c
>
'
9
'
)
&& c
!=
'
-
'
; c
=
getc
())
{
assert
(
~c
);
}
if
(c
==
'
-
'
)
{
pos
=
false
;
c
=
getc
();
}
for
(; c
>=
'
0
'
&& c
<=
'
9
'
; c
=
getc
())
{
ret
=
(ret
<<
3
)
+
(ret
<<
1
)
+
(c
^
48
);
}
return pos
? ret
:
-ret
;
}
const
int maxn
=
2e5
+
7
;
int a
[maxn
];
int n
;
int head
[maxn
<<
1
], edge
[maxn
<<
1
], nxt
[maxn
<<
1
], cnt
;
int f
[maxn
];
bool vis
[maxn
];
int ans
[maxn
];
void
BuildGraph
(
int
u
,
int
v
)
{
cnt
++
;
edge
[cnt
]
= v
;
nxt
[cnt
]
= head
[u
];
head
[u
]
= cnt
;
}
void
dfs
(
int
u
,
int
fa
)
{
if
(a
[u
]
==
1
)
{
f
[u
]
=
1
;
}
else
{
f
[u
]
=
-
1
;
}
//printf("f[%d]:%d\n",u, f[u]);
for
(
int i
= head
[u
]; i
; i
= nxt
[i
]
)
{
int v
=
edge
[i
];
if
(v
== fa
)
continue
;
else
{
dfs
(v
, u
);
if
(
f
[v
]
>
0
)
{
f
[u
]
+=
f
[v
];
//printf("f[%d]:%d\n",u, f[u]);
}
}
}
}
void
dp
(
int
u
,
int
fa
)
{
if
(f
[u
]
>=
0
)
{
int temp
=
f
[fa
]
-
f
[u
];
if
(temp
>=
0
)
{
f
[u
]
+= temp
;
//printf("f[%d]:%d\n",u, f[u]);
}
}
else
{
//printf("fa: f[%d]:%d\n",fa, f[fa]);
if
(
f
[fa
]
>=
0
)
{
f
[u
]
+=
f
[fa
];
//printf("f[%d]:%d\n",u, f[u]);
}
}
for
(
int i
= head
[u
]; i
; i
= nxt
[i
]
)
{
int v
=
edge
[i
];
//dbg(v);
if
(v
== fa
)
continue
;
else
{
dp
(v
, u
);
}
}
}
int
main
()
{
read
(n
);
for
(
int i
=
1
; i
<= n
;
++i
)
{
read
(
a
[i
]);
}
for
(
int i
=
1
; i
< n
;
++i
)
{
int u
, v
;
read
(u
);
read
(v
);
BuildGraph
(u
, v
);
BuildGraph
(v
, u
);
}
dfs
(
1
,
1
);
dp
(
1
,
1
);
for
(
int i
=
1
; i
<= n
;
++i
)
{
printf
(
"%d
"
,
f
[i
]);
}
return
0
;
}