#include using namespace std; const int MAXN = 5010; const int oo = 1E9; int n; int cost[MAXN][MAXN]; int u[MAXN], v[MAXN]; int best[MAXN], bestp[MAXN]; int match[2 * MAXN], used[MAXN]; #define GET(x, y) (cost[x][y] - u[x] - v[y]) void HungarianAlg(){ memset(u, 0, n * sizeof(int)); memset(v, 0, n * sizeof(int)); memset(match, -1, 2 * n * sizeof(int)); for(int row = 0;row < n;++row){ memset(used, 0, (row + 1) * sizeof(int)); used[row] = true; for(int i = 0;i < n;++i) best[i] = GET(row, i), bestp[i] = row; while(true){ int delta = oo, nxt; for(int i = 0;i < n;++i) if(delta > best[i]) delta = best[i], nxt = i; for(int i = 0;i < n;++i){ if(used[i]) u[i] += delta; if(best[i] == oo) v[i] -= delta; else best[i] -= delta; } best[nxt] = oo; if(match[n + nxt] == -1){ while(nxt != -1){ int prev = match[bestp[nxt]]; match[n + nxt] = bestp[nxt]; match[bestp[nxt]] = nxt; nxt = prev; } break; } else { int vr = match[n + nxt]; used[vr] = true; for(int i = 0;i < n;++i) if(best[i] != oo && best[i] > GET(vr, i)) best[i] = GET(vr, i), bestp[i] = vr; } } } } int main(){ n = 4; cost[0][0] = 82; cost[0][1] = 83; cost[0][2] = 69; cost[0][3] = 92; cost[1][0] = 77; cost[1][1] = 37; cost[1][2] = 49; cost[1][3] = 92; cost[2][0] = 11; cost[2][1] = 69; cost[2][2] = 5; cost[2][3] = 86; cost[3][0] = 8; cost[3][1] = 9; cost[3][2] = 98; cost[3][3] = 23; HungarianAlg(); for(int i = 0;i < n;++i) cout << i << ' ' << match[i] << '\n'; return 0; }