Rerooting uses two DFS passes. First pass: pick an arbitrary root (usually node ) and compute subtree answers going down. This is standard tree DP you already know. Second pass: propagate information from parent to child going down again. For each node, combine the subtree answer with the contribution from its parent (which includes the parent's parent, and so on).
After both passes, every node has the answer as if it were the root. Total time: per pass, overall. No recomputation, no wasted work.
Space complexity is for the data structures used.