Gale-Shapley Algorithm
此算法的流程如下:
首先搞一个队列,存储未匹配的男士编号。每次取出一个未匹配的男士的编号,让他向其未求过婚的且最喜欢的女士求婚,如果对应女士没有匹配或者已经匹配的没有这位优,那么将这位与对应的女士相匹配,并且将原来已匹配的男士扔到队列里,一直重复上述步骤直到队列为空
可以证明,上述流程结束后,每位男士必定有配偶,且婚姻是稳定的
例题
1.UVA1175 Ladies' Choice
最简单的板子,直接上代码,抄的大刘的
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <cmath>
#include <ctime>
#include <queue>
#include <map>
#include <set>
using namespace std;
#define ull unsigned long long
#define pii pair<int, int>
#define uint unsigned int
#define mii map<int, int>
#define lbd lower_bound
#define ubd upper_bound
#define INF 0x3f3f3f3f
#define IINF 0x3f3f3f3f3f3f3f3fLL
#define DEF 0x8f8f8f8f
#define DDEF 0x8f8f8f8f8f8f8f8fLL
#define vi vector<int>
#define ll long long
#define mp make_pair
#define pb push_back
#define re register
#define il inline
#define N 1000
int pref[N+5][N+5], order[N+5][N+5], nxt[N+5];
int futureHusband[N+5], futureWife[N+5];
queue<int> q;
void engage(int man, int woman) {
int m = futureHusband[woman];
if(m) {
futureWife[m] = 0;
q.push(m);
}
futureWife[man] = woman;
futureHusband[woman] = man;
}
int main() {
int T;
scanf("%d", &T);
while(T--) {
int n;
scanf("%d", &n);
for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= n; ++j) scanf("%d", &pref[i][j]);
nxt[i] = 1;
futureWife[i] = 0;
q.push(i);
}
for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= n; ++j) {
int x;
scanf("%d", &x);
order[i][x] = j;
}
futureHusband[i] = 0;
}
while(!q.empty()) {
int man = q.front(); q.pop();
int woman = pref[man][nxt[man]++];
if(!futureHusband[woman]) engage(man, woman);
else if(order[woman][man] < order[woman][futureHusband[woman]]) engage(man, woman);
else q.push(man);
}
while(!q.empty()) q.pop();
for(int i = 1; i <= n; ++i) printf("%d\n", futureWife[i]);
if(T) printf("\n");
}
return 0;
}