Some problems require tracking multiple values in the DP state. For example, you might need both the count of nodes and the sum of distances, or both the maximum and second-maximum values. In these cases, down[v] becomes a struct or tuple with several fields. up[v] does the same.
Your combine function takes two structs and returns a merged struct. This does not change the two-pass structure. It makes the bookkeeping more complex. You still do down pass, up pass, and then combine down[v] and up[v] for the final answer.