Stable Marriage Problem and Propose-and-reject algorithm
有n位男士,n位女士,每个人对于每个异性都有一个排序,表示对他(她)的喜欢程度。现在要求他们两两(异性)组成稳定的关系,对于稳定的关系定义如下,不存在任何一对男女,他们对对方的喜欢程度都大于他们当前的伴侣。
以上,便是Stable Marriage Problem的定义。
对于稳定婚姻关系,Gale-Shapley算法可解。该算法根据其特点亦被称作Propose-and-reject algorithm,求婚-拒绝算法。
详细过程是,每一轮每个男士都向他还没求婚过的女士中他最喜欢的那个求婚,而每位女士则在所有向她求婚的男士中选择一个她最喜欢的作为伴侣,并且拒绝其他男士。
看起来,这个方法对男士很残酷,因为他们一直在被选择,但结果却是另一番景象,所有的男士都与他可能结为伴侣的最喜欢的女士结成了伴侣,而所有女士却是和与她可能结为伴侣的最不喜欢的男士结成了伴侣。
所以,在爱情里,掌握主动权才是关键?
//#include<bits/stdc++.h>
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<queue>
#define LS (root<<1)
#define RS ((root<<1)|1)
#define LSON LS,l,mid
#define RSON RS,(mid+1),r
#define MID mid=((l+r)/2)
#define LL long long
#define mm(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn=1e3+5;
const LL Inf=1e18;
int pref[maxn][maxn], order[maxn][maxn];
int future_wife[maxn], future_husband[maxn];
int _next[maxn];
queue<int> q;
void engage(int man,int woman){
int husband=future_husband[woman];
if(husband){
q.push(husband);
future_wife[husband]=0;
}
future_husband[woman]=man;
future_wife[man]=woman;
}
int main(){//propose and reject algorithm
int T, n;
LL L, R;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)
scanf("%d",&pref[i][j]);
_next[i]=1;
future_wife[i]=0;
q.push(i);//待求婚的男士入队
}
for(int i=1;i<=n;i++){
int x;
for(int j=1;j<=n;j++){
scanf("%d",&x);
order[i][x]=j;//order记录女士心中男士x的排名
}
future_husband[i]=0;
}
while(!q.empty()){
int man=q.front(); q.pop();//找一个未娶妻的男士出来求婚
int woman=pref[man][_next[man]++];//对当前未求过婚的最爱的女士求婚
if(future_husband[woman]==0)//女士尚未订婚
engage(man,woman);//订婚
else if(order[woman][man]<order[woman][future_husband[woman]])//女士不爱未婚夫更爱男士
engage(man,woman);//订婚
else//女士更爱未婚夫,男士重新入队, 等待下一轮求婚
q.push(man);
}
for(int i=1;i<=n;i++)
printf("%d\n",future_wife[i]);
if(T) puts("");
}
return 0;
}