poj 3487 The Stable Marriage Problem(稳定婚姻问题)

这篇博客介绍了稳定婚姻问题的背景和定义,并提出了一个特殊的问题,即寻找男性最优的稳定婚姻匹配。文章提供了一个输入格式说明,包括男性和女性的偏好列表,要求找到满足稳定条件且对男性最有利的匹配方案。内容包括多组测试用例,每组用例输出匹配的男女组合,按男性名字的字典序排列。

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

The Stable Marriage Problem
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 2130 Accepted: 908

Description

The stable marriage problem consists of matching members of two different sets according to the member’s preferences for the other set’s members. The input for our problem consists of:

  • a set M of n males;
  • a set F of n females;
  • for each male and female we have a list of all the members of the opposite gender in order of preference (from the most preferable to the least).

A marriage is a one-to-one mapping between males and females. A marriage is called stable, if there is no pair (m, f) such that f ∈ F prefers m ∈ M to her current partner and m prefers f over his current partner. The stable marriage A is called male-optimal if there is no other stable marriage B, where any male matches a female he prefers more than the one assigned in A.

Given preferable lists of males and females, you must find the male-optimal stable marriage.

Input

The first line gives you the number of tests. The first line of each test case contains integer n (0 < n < 27). Next line describes n male and n female names. Male name is a lowercase letter, female name is an upper-case letter. Then go n lines, that describe preferable lists for males. Next n lines describe preferable lists for females.

Output

For each test case find and print the pairs of the stable marriage, which is male-optimal. The pairs in each test case must be printed in lexicographical order of their male names as shown in sample output. Output an empty line between test cases.

Sample Input

2
3
a b c A B C
a:BAC
b:BAC
c:ACB
A:acb
B:bac
C:cab
3
a b c A B C
a:ABC
b:ABC
c:BCA
A:bac
B:acb
C:abc

Sample Output

a A
b B
c C

a B
b A
c C

题意:有n个男士和n个女士。给出每个男士喜欢的女士排列,从最喜欢到最不喜欢;给出每个女士喜欢的男士排列,也是从最喜欢到最不喜欢。现在要求找出所有的配对,使得任意一个男士m和任意一个女士f,不存在f喜欢m比与f配对的男士多,或者m喜欢f比与m配对的女士多的情况。即稳定婚姻问题。
思路:Gale-Shapley算法。算法过程是男士不停地求婚,女士不停地拒绝。在每一轮中,每个尚未订婚的男士在他还没有求过婚的女士中选一个自己最喜欢的求婚(不管她有没有订婚)。然后每个女士在向她求婚的人之中选择她最喜欢的一个订婚,并且拒绝其他人。注意,这些向她求婚的人中包含她的未婚夫,因此她可以选择另一个自己更喜欢的人订婚,而抛弃自己的现任未婚夫。这个算法的结果是使男士都能娶到自己有可能娶到的最好的妻子,所以是对男士的理想配对。

AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <vector>
#include <cmath>
#include <cstdlib>
#define L(rt) (rt<<1)
#define R(rt) (rt<<1|1)
#define ll long long
#define eps 1e-6
using namespace std;

const int maxn=30;
const int INF=1000000000;
int order[maxn][maxn],pre[maxn][maxn],next[maxn];
int future_h[maxn],future_w[maxn],hash[100];
queue<int>Q;
int n;
void engage(int man,int woman)
{
    int m=future_h[woman];
    if(m)
    {
        future_w[m]=0;
        Q.push(m);
    }
    future_h[woman]=man;
    future_w[man]=woman;
}
int main()
{
    int t,cnt;
    char s[50],female[maxn];
    scanf("%d",&t);
    while(t--)
    {
        memset(hash,-1,sizeof(hash));
        scanf("%d",&n);
        cnt=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%s",s);
            hash[s[0]-'A']=++cnt;
        }
        cnt=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%s",s);
            hash[s[0]-'A']=++cnt;
            female[cnt]=s[0];
        }
        for(int i=1;i<=n;i++)
        {
            scanf("%s",s);
            int u=hash[s[0]-'A'];
            cnt=0;
            for(int j=2;j<n+2;j++)
            pre[u][++cnt]=hash[s[j]-'A'];
            next[u]=1;
            future_w[u]=0;
            Q.push(u);
        }
        for(int i=1;i<=n;i++)
        {
            scanf("%s",s);
            int u=hash[s[0]-'A'];
            cnt=0;
            for(int j=2;j<n+2;j++)
            {
                int v=hash[s[j]-'A'];
                order[u][v]=++cnt;
            }
            future_h[u]=0;
        }
        while(!Q.empty())
        {
            int man=Q.front();
            Q.pop();
            int woman=pre[man][next[man]++];
            if(!future_h[woman]) engage(man,woman);
            else if(order[woman][man]<order[woman][future_h[woman]]) engage(man,woman);
            else Q.push(man);
        }
        while(!Q.empty()) Q.pop();
        for(int i=32;i<=60;i++)
        if(hash[i]!=-1)
        printf("%c %c\n",'A'+i,female[future_w[hash[i]]]);
        if(t) puts("");
    }
    return 0;
}


开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值