Parallelizing an algorithm with OpenMP using a dynamic work queue
Firstly, I know you said you're not so interested in a style review, but:

using namespace std;


Apart from being harmful, this isn't even bringing any benefit.  We can just drop it with no changes to the rest of the code.

And if OpenMP is correctly installed, the header should be on the include path (not in your source code location):

#include &lt;omp.h&gt;




The only thing we use from &lt;omp.h&gt; is omp_get_num_threads(); we can avoid needing that if we change the sense of the numWaiting variable, so we get to compare against zero instead:

    unsigned int num_working = 0;




#pragma omp parallel
{
#pragma omp single
    ++num_working;

    while (true) {
        std::unique_lock&lt;std::mutex&gt; lock(m);

        if (workStack.empty()) {
            --num_working;

            if (num_working == 0) {
                cv.notify_all();
                break;
            }

            while (true) {
                cv.wait(lock);
                if (num_working == 0 || !workStack.empty()) break;
            }

            if (num_working == 0) break;

            ++num_working;
        }


Instead of the #pragma omp single, we could make num_working be a std::atomic&lt;unsigned&gt; instead.



When we add two items to the work queue, we only wake up one worker thread.  We need to wake up a thread for each child, potentially:

        workStack.push(childA);
        cv.notify_one();
        workStack.push(childB);
        cv.notify_one();




Possibly a style issue, but the while (true) loop looks better as a do ... while:

            do {
                cv.wait(lock);
            } while (num_working &gt; 0 &amp;&amp; workStack.empty());