LA 3989

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值