//
// main.cpp
// Stable Matching Problem (Gale-Shapley algorithm)
//
// Created by Himanshu on 19/03/24.
//
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
void printCurrentState (const vector<int> match, const vector<bool> engaged) {
int n = (int) match.size();
cout << endl << "Current matched pairs (w, m):" << endl;
for (int i = 0; i < n; i++) {
cout << "(" << i << ", " << match[i] << ")" << endl;
}
cout << "Free men (m): " << endl;
for (int i = 0; i < n; i++) {
if (!engaged[i]) {
cout << i << " ";
}
}
cout << endl;
}
vector<int> stableMarriage(const vector<vector<int>>& manPrefs, const vector<vector<int>>& womanPrefs) {
int n = (int) manPrefs.size();
vector<int> match(n, -1); // Stores the matched man for each woman, -1 means unengaged
vector<bool> engaged(n, false); // Indicates whether a man is engaged
// Queue to store the list of free men
queue<int> freeMen;
for (int i = 0; i < n; i++) freeMen.push(i);
while (!freeMen.empty()) {
int man = freeMen.front(); // Index of the unengaged man
freeMen.pop();
// Find the best woman based on the man's preference list who has not rejected him
for (int i = 0; i < n && !engaged[man]; i++) {
int woman = manPrefs[man][i]; // man's most preferred woman
// if the man's current preferred woman is unengaged
if (match[woman] == -1) {
match[woman] = man; // Engage the man to the woman
engaged[man] = true;
printCurrentState(match, engaged);
} else {
int prevMatchedMan = match[woman];
//if woman prefer current "man" over previously matched man
if (find(womanPrefs[woman].begin(), womanPrefs[woman].end(), man) < find(womanPrefs[woman].begin(), womanPrefs[woman].end(), prevMatchedMan)) {
match[woman] = man; // Engage the current man to the woman
engaged[man] = true;
engaged[prevMatchedMan] = false; // Break the engagement with previous man
freeMen.push(prevMatchedMan);
printCurrentState(match, engaged);
}
}
}
}
return match;
}
int main() {
vector<vector<int>> menPrefs = {
{1, 0, 2, 3},
{3, 1, 0, 2},
{0, 2, 1, 3},
{1, 3, 2, 0}
};
vector<vector<int>> womenPrefs = {
{0, 1, 2, 3},
{1, 2, 3, 0},
{2, 3, 0, 1},
{3, 0, 1, 2}
};
vector<int> pairs = stableMarriage(menPrefs, womenPrefs);
cout << "Stable pairings:" << endl;
for (int i = 0; i < pairs.size(); i++) {
cout << "Woman " << i << " is paired with Man " << pairs[i] << endl;
}
return 0;
}
Ly8KLy8gIG1haW4uY3BwCi8vICBTdGFibGUgTWF0Y2hpbmcgUHJvYmxlbSAoR2FsZS1TaGFwbGV5IGFsZ29yaXRobSkKLy8KLy8gIENyZWF0ZWQgYnkgSGltYW5zaHUgb24gMTkvMDMvMjQuCi8vCiAKI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8cXVldWU+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CiAKdm9pZCBwcmludEN1cnJlbnRTdGF0ZSAoY29uc3QgdmVjdG9yPGludD4gbWF0Y2gsIGNvbnN0IHZlY3Rvcjxib29sPiBlbmdhZ2VkKSB7CiAgICAKICAgIGludCBuID0gKGludCkgbWF0Y2guc2l6ZSgpOwogICAgCiAgICBjb3V0IDw8IGVuZGwgPDwgIkN1cnJlbnQgbWF0Y2hlZCBwYWlycyAodywgbSk6IiA8PCBlbmRsOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgICAgICBjb3V0IDw8ICIoIiA8PCBpIDw8ICIsICIgPDwgbWF0Y2hbaV0gPDwgIikiIDw8IGVuZGw7CiAgICB9CiAgICAKICAgIGNvdXQgPDwgIkZyZWUgbWVuIChtKTogIiA8PCBlbmRsOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgICAgICBpZiAoIWVuZ2FnZWRbaV0pIHsKICAgICAgICAgICAgY291dCA8PCBpIDw8ICIgIjsKICAgICAgICB9CiAgICB9CiAgICAKICAgIGNvdXQgPDwgZW5kbDsKICAgIAp9CiAKdmVjdG9yPGludD4gc3RhYmxlTWFycmlhZ2UoY29uc3QgdmVjdG9yPHZlY3RvcjxpbnQ+PiYgbWFuUHJlZnMsIGNvbnN0IHZlY3Rvcjx2ZWN0b3I8aW50Pj4mIHdvbWFuUHJlZnMpIHsKICAgIGludCBuID0gKGludCkgbWFuUHJlZnMuc2l6ZSgpOwogICAgIAogICAgdmVjdG9yPGludD4gbWF0Y2gobiwgLTEpOyAvLyBTdG9yZXMgdGhlIG1hdGNoZWQgbWFuIGZvciBlYWNoIHdvbWFuLCAtMSBtZWFucyB1bmVuZ2FnZWQKICAgIHZlY3Rvcjxib29sPiBlbmdhZ2VkKG4sIGZhbHNlKTsgLy8gSW5kaWNhdGVzIHdoZXRoZXIgYSBtYW4gaXMgZW5nYWdlZAogICAgIAogICAgLy8gUXVldWUgdG8gc3RvcmUgdGhlIGxpc3Qgb2YgZnJlZSBtZW4KICAgIHF1ZXVlPGludD4gZnJlZU1lbjsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSBmcmVlTWVuLnB1c2goaSk7CiAgICAgCiAgICB3aGlsZSAoIWZyZWVNZW4uZW1wdHkoKSkgewogICAgICAgICAKICAgICAgICBpbnQgbWFuID0gZnJlZU1lbi5mcm9udCgpOyAvLyBJbmRleCBvZiB0aGUgdW5lbmdhZ2VkIG1hbgogICAgICAgIGZyZWVNZW4ucG9wKCk7CiAgICAgICAgIAogICAgICAgIC8vIEZpbmQgdGhlIGJlc3Qgd29tYW4gYmFzZWQgb24gdGhlIG1hbidzIHByZWZlcmVuY2UgbGlzdCB3aG8gaGFzIG5vdCByZWplY3RlZCBoaW0KICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG4gJiYgIWVuZ2FnZWRbbWFuXTsgaSsrKSB7CiAgICAgICAgICAgICAKICAgICAgICAgICAgaW50IHdvbWFuID0gbWFuUHJlZnNbbWFuXVtpXTsgLy8gbWFuJ3MgbW9zdCBwcmVmZXJyZWQgd29tYW4KICAgICAgICAgICAgIAogICAgICAgICAgICAvLyBpZiB0aGUgbWFuJ3MgY3VycmVudCBwcmVmZXJyZWQgd29tYW4gaXMgdW5lbmdhZ2VkCiAgICAgICAgICAgIGlmIChtYXRjaFt3b21hbl0gPT0gLTEpIHsKICAgICAgICAgICAgICAgIG1hdGNoW3dvbWFuXSA9IG1hbjsgLy8gRW5nYWdlIHRoZSBtYW4gdG8gdGhlIHdvbWFuCiAgICAgICAgICAgICAgICBlbmdhZ2VkW21hbl0gPSB0cnVlOwogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBwcmludEN1cnJlbnRTdGF0ZShtYXRjaCwgZW5nYWdlZCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpbnQgcHJldk1hdGNoZWRNYW4gPSBtYXRjaFt3b21hbl07CiAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAvL2lmIHdvbWFuIHByZWZlciBjdXJyZW50ICJtYW4iIG92ZXIgcHJldmlvdXNseSBtYXRjaGVkIG1hbgogICAgICAgICAgICAgICAgaWYgKGZpbmQod29tYW5QcmVmc1t3b21hbl0uYmVnaW4oKSwgd29tYW5QcmVmc1t3b21hbl0uZW5kKCksIG1hbikgPCBmaW5kKHdvbWFuUHJlZnNbd29tYW5dLmJlZ2luKCksIHdvbWFuUHJlZnNbd29tYW5dLmVuZCgpLCBwcmV2TWF0Y2hlZE1hbikpIHsKIAogICAgICAgICAgICAgICAgICAgIG1hdGNoW3dvbWFuXSA9IG1hbjsgLy8gRW5nYWdlIHRoZSBjdXJyZW50IG1hbiB0byB0aGUgd29tYW4KICAgICAgICAgICAgICAgICAgICBlbmdhZ2VkW21hbl0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICBlbmdhZ2VkW3ByZXZNYXRjaGVkTWFuXSA9IGZhbHNlOyAvLyBCcmVhayB0aGUgZW5nYWdlbWVudCB3aXRoIHByZXZpb3VzIG1hbgogICAgICAgICAgICAgICAgICAgIGZyZWVNZW4ucHVzaChwcmV2TWF0Y2hlZE1hbik7CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgcHJpbnRDdXJyZW50U3RhdGUobWF0Y2gsIGVuZ2FnZWQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgIAogICAgcmV0dXJuIG1hdGNoOwp9CiAKaW50IG1haW4oKSB7CiAgICAgCiAgICB2ZWN0b3I8dmVjdG9yPGludD4+IG1lblByZWZzID0gewogICAgICAgIHsxLCAwLCAyLCAzfSwKICAgICAgICB7MywgMSwgMCwgMn0sCiAgICAgICAgezAsIDIsIDEsIDN9LAogICAgICAgIHsxLCAzLCAyLCAwfQogICAgfTsKICAgIHZlY3Rvcjx2ZWN0b3I8aW50Pj4gd29tZW5QcmVmcyA9IHsKICAgICAgICB7MCwgMSwgMiwgM30sCiAgICAgICAgezEsIDIsIDMsIDB9LAogICAgICAgIHsyLCAzLCAwLCAxfSwKICAgICAgICB7MywgMCwgMSwgMn0KICAgIH07CiAgICAgCiAgICB2ZWN0b3I8aW50PiBwYWlycyA9IHN0YWJsZU1hcnJpYWdlKG1lblByZWZzLCB3b21lblByZWZzKTsKICAgICAKICAgIGNvdXQgPDwgIlN0YWJsZSBwYWlyaW5nczoiIDw8IGVuZGw7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhaXJzLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY291dCA8PCAiV29tYW4gIiA8PCBpIDw8ICIgaXMgcGFpcmVkIHdpdGggTWFuICIgPDwgcGFpcnNbaV0gPDwgZW5kbDsKICAgIH0KICAgICAKICAgIHJldHVybiAwOwp9Cg==
Current matched pairs (w, m):
(0, -1)
(1, 0)
(2, -1)
(3, -1)
Free men (m):
1 2 3
Current matched pairs (w, m):
(0, -1)
(1, 0)
(2, -1)
(3, 1)
Free men (m):
2 3
Current matched pairs (w, m):
(0, 2)
(1, 0)
(2, -1)
(3, 1)
Free men (m):
3
Current matched pairs (w, m):
(0, 2)
(1, 3)
(2, -1)
(3, 1)
Free men (m):
0
Current matched pairs (w, m):
(0, 0)
(1, 3)
(2, -1)
(3, 1)
Free men (m):
2
Current matched pairs (w, m):
(0, 0)
(1, 3)
(2, 2)
(3, 1)
Free men (m):
Stable pairings:
Woman 0 is paired with Man 0
Woman 1 is paired with Man 3
Woman 2 is paired with Man 2
Woman 3 is paired with Man 1