You can simply pass the top object to the children and call a function directly on it. This guarantees that you don't have to rely on parent propagation. So you don't end up doing silly things like transform.parent.parent
You could however automate this process with GetComponentInParent. This retrieves the first script it finds. Then cache that in your collision object, directly call functions on said cached object.
This will retrieve the first occurring script that it finds.
Alternatively you could make use of UnityEvents ( don't use Messages ) to bind functions to the child object. With unity events you can add any arbitrary listener so you can do more than just notify the top level object of the child object being hit.