Lets consider the case where you need to be $O(V+E)$. As someone in the comments mentioned, the way I thought about it was reversing the edges, as described below:
- Reverse all edges
- For every unvisited black vertex, perform a BFS/DFS on all unvisited nodes, marking them visited as you search.
- All visited nodes are good.
It is trivial to see that if and only if a node is marked visited, it can reach a black vertex in the original graph. The forward direction is simple, if a node is visited, then there is a direct path to a black vertex. The other direction is also true, if there is a path from a node to a black vertex in the original graph, that that node would clearly have been visited by one of the searches.
Now, let's say you want to stick with the SCC strategy. We first find all SCC's in $O(V+E)$ time. Then, for each SCC we condense it to a single node and color it black if it contained a black node and red otherwise. All edges into and out of the each SCC will now lead into and out of the new corresponding condensed node. Now we can just perform the same algorithm as above on the new graph with no SCCs! For every node, mark it as good iff its corresponding SCC was visited.