1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
class Solution {
public:
pair<vector<pair<string, string>>, bool> stableMarriageWithVerification(
unordered_map<string, vector<string>>& guyPrefs,
unordered_map<string, vector<string>>& galPrefs) {
// First, find matching using Gale-Shapley
auto matching = galeShapley(guyPrefs, galPrefs);
// Convert to maps for easier verification
unordered_map<string, string> guyToGal, galToGuy;
for (auto& [guy, gal] : matching) {
guyToGal[guy] = gal;
galToGuy[gal] = guy;
}
// Verify stability
bool isStable = verifyStability(guyPrefs, galPrefs, guyToGal, galToGuy);
return {matching, isStable};
}
private:
vector<pair<string, string>> galeShapley(
unordered_map<string, vector<string>>& guyPrefs,
unordered_map<string, vector<string>>& galPrefs) {
// Create preference rankings
unordered_map<string, unordered_map<string, int>> galRankings;
for (auto& [gal, prefs] : galPrefs) {
for (int i = 0; i < prefs.size(); i++) {
galRankings[gal][prefs[i]] = i;
}
}
unordered_map<string, int> guyNextProposal;
unordered_map<string, string> galPartner, guyPartner;
queue<string> freeGuys;
for (auto& [guy, _] : guyPrefs) {
freeGuys.push(guy);
guyNextProposal[guy] = 0;
}
while (!freeGuys.empty()) {
string guy = freeGuys.front();
freeGuys.pop();
string gal = guyPrefs[guy][guyNextProposal[guy]];
guyNextProposal[guy]++;
if (galPartner.find(gal) == galPartner.end()) {
galPartner[gal] = guy;
guyPartner[guy] = gal;
} else {
string currentPartner = galPartner[gal];
if (galRankings[gal][guy] < galRankings[gal][currentPartner]) {
galPartner[gal] = guy;
guyPartner[guy] = gal;
guyPartner.erase(currentPartner);
freeGuys.push(currentPartner);
} else {
freeGuys.push(guy);
}
}
}
vector<pair<string, string>> result;
for (auto& [guy, gal] : guyPartner) {
result.push_back({guy, gal});
}
return result;
}
bool verifyStability(unordered_map<string, vector<string>>& guyPrefs,
unordered_map<string, vector<string>>& galPrefs,
unordered_map<string, string>& guyToGal,
unordered_map<string, string>& galToGuy) {
// Create rankings for efficient preference comparison
unordered_map<string, unordered_map<string, int>> guyRankings, galRankings;
for (auto& [guy, prefs] : guyPrefs) {
for (int i = 0; i < prefs.size(); i++) {
guyRankings[guy][prefs[i]] = i;
}
}
for (auto& [gal, prefs] : galPrefs) {
for (int i = 0; i < prefs.size(); i++) {
galRankings[gal][prefs[i]] = i;
}
}
// Check for blocking pairs
for (auto& [guy, guyPrefList] : guyPrefs) {
for (auto& [gal, galPrefList] : galPrefs) {
if (guyToGal[guy] == gal) continue; // Already matched
string guyCurrentPartner = guyToGal[guy];
string galCurrentPartner = galToGuy[gal];
// Check if guy prefers gal over his current partner
bool guyPrefers = guyRankings[guy][gal] < guyRankings[guy][guyCurrentPartner];
// Check if gal prefers guy over her current partner
bool galPrefers = galRankings[gal][guy] < galRankings[gal][galCurrentPartner];
if (guyPrefers && galPrefers) {
return false; // Blocking pair found
}
}
}
return true; // No blocking pairs found
}
};
|