Problem. workers, jobs, a cost matrix . Assign each worker to exactly one job minimising the total cost.

Equivalently: a minimum-cost perfect matching in a complete bipartite graph.

The methods

MethodTimeFeasible
Brute force over permutations10
Bitmask DP20
Hungarian algorithm500-1000
Min-cost flow (SSP + potentials)500
Gabow-Tarjan scalingtheoretical
Auction algorithmparallelisable
Greedynot optimal

Write the Hungarian algorithm for , bitmask DP below that.

Bitmask DP — the easy option

long long assignment(int n, vector<vector<long long>>& c) {
    vector<long long> dp(1 << n, LLONG_MAX / 2);
    dp[0] = 0;
    for (int mask = 0; mask < (1 << n); mask++) {
        int i = __builtin_popcount(mask);                // next worker to assign
        if (i == n || dp[mask] == LLONG_MAX / 2) continue;
        for (int j = 0; j < n; j++)
            if (!(mask >> j & 1))
                dp[mask | (1 << j)] = min(dp[mask | (1 << j)], dp[mask] + c[i][j]);
    }
    return dp[(1 << n) - 1];
}

Using popcount(mask) to derive the worker index removes an entire dimension. — instant for , and far easier to get right than Hungarian.

The Hungarian algorithm in one paragraph

Maintain dual potentials (workers) and (jobs) with . Edges achieving equality form the tight subgraph; grow an alternating tree in it, and when stuck, adjust the potentials by the minimum slack to expose new tight edges. Each of phases matches one more worker in , giving .

The invariant is LP duality: at the end equals the optimum, which is a certificate of optimality. See Hungarian Algorithm.

Variants

VariantMethod
Maximise instead of minimisenegate the costs, or subtract from the maximum
Rectangular ()pad with zero-cost dummy rows or columns
Some assignments forbiddenset those costs to
Bottleneck assignment (minimise the max cost)binary search + bipartite matching
Workers handle jobsmin-cost flow with capacities
Costs change over timerecompute, or use the incremental Hungarian
Non-bipartite (general graph)weighted Blossom
Only feasibility (any perfect matching)Hopcroft-Karp,
3-dimensional assignmentNP-hard

Bottleneck assignment is worth calling out: binary search the threshold , keep only edges with cost , and test for a perfect matching. and much simpler than a specialised algorithm — the standard “binary search + feasibility” pattern.

Why greedy fails

Assigning the globally cheapest pair, then the next, and so on, is not optimal:

Greedy takes then is forced into , total 101. The optimum is .

The failure is instructive: greedy has no way to account for the opportunity cost of a choice, which is exactly what the Hungarian algorithm’s dual potentials encode.

Recognising it

The assignment problem hides behind many phrasings:

  • “match each person to a task minimising total time”,
  • “pair up points to minimise total distance” (with two colour classes),
  • “assign each row a distinct column with minimum penalty”,
  • “select one element from each row, all in distinct columns”.

Whenever a problem needs a bijection between two sets of size with an additive cost, it is this problem.

Why it is worth knowing

It is the canonical example of a problem where:

  • the naive greedy is wrong,
  • the exponential search is unnecessary,
  • and a polynomial algorithm exists via LP duality.

The dual potentials also reappear in min-cost flow and Johnson’s reweighting, so understanding them once pays off repeatedly.

See also: Hungarian Algorithm · Min-Cost Flow · Bitmask DP