Here is the solution:
c = array of node colors (1 or -1)
dp = array of size n
ans = array of size n
function dfs1(u, p):
dp[u] = c[u]
for v in adj[u]:
if v == p:
continue
dfs1(v, u)
dp[u] = dp[u] + max(0, dp[v])
function dfs2(u, p, up):
ans[u] = dp[u] + max(0, up)
for v in adj[u]:
if v == p:
continue
newUp = c[u] + max(0, up) + (dp[u] - c[u] - max(0, dp[v]))
dfs2(v, u, newUp)
This runs in time and uses space.