思考
右、最大点を見つけるために右の部分木に少し黒と白の1ビットので-1権利。
セットF [I]はI重量ポイントを含むサブツリーの最高点である場合の最大点と現在の点の重量 比 と最大電流点右点父親の小さなは、現在のポイントが更新されます。
比較愚かなアプローチは、右と現在のポイントは、0未満またはプロセスが異なる点である場合よりも大きい、次の2つの場合に議論されています。
もし現在のアイデアツリーの重み> = 0、そして父の右部分木の大きい値、すべきサブツリーの現在位置に父親サブツリーのマージポイント。
黒よりも現在のツリーのアイデアの重み<0、と父のサブツリーより白い場合は、現在のポイントと合併サブツリーの父ツリーにポイントを置きます。
コード
#include
<
ビット/ STDC ++。H
>
#define
DBG
(
X
)
COUT
<<
#X
<<
"
=
"
<<
X
<<
ENDL
#define
EPS
1E
-
8
#define
パイ
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
;
}