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;
}