【hdu】The Stable Marriage Problem(婚姻匹配问题/稳定匹配)

Problem 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个女,男生的名字是一个小写字母,女生的名字是大写字母。现在要让他们凑成n对,每个男的都有中意的女生排序,女生也有中意的男生排序,如果有a和B配对,c和D配对,但是a中意的男生排序中D排在B前面,并且D中意的女生排序中a排在c前面,那么a,D可能会私奔,所以这样的排序是不稳定的。现在就要找到稳定匹配的排序。

【题解】:这是一个婚姻匹配算法,让男生按照中意女生的顺序依次去匹配女生,女生单身的话就接受,女生不单身就比较这个男生和现任男友,如果更中意男生就抛弃男友,否则拒绝男生。循环,直到所有人匹配完毕。

【总结】:1.输入的时候一个技巧,男生输入中意女生的排序,女生输入的是中意男生编号,这样和现男友比较的时候比较方便。
2.男生最后输出的时候是按照字母顺序的需要注意一下
3.这题有输出格式坑

代码

#include <bits/stdc++.h>
using namespace std;
int people[30];//存男生字母

int manf[30][30];//男生喜欢排序
int womanf[30][30];//女生喜欢排序

int manc[30];//男生选择到第几个妹子了
int manp[30];//男生匹配的妹子是
int womanc[30];//女生目前的选择

int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        int n;
        cin>>n;
        memset(manc,-1,sizeof(manc));
        memset(womanc,-1,sizeof(manc));
        memset(manp,0,sizeof(manc));
        memset(people,0,sizeof(people));
        string s;
        for(int i=0;i<n;i++)
        {
            cin>>s;
            people[s[0]-'a']=1;
        }

        for(int i=0;i<n;i++)
        {
           cin>>s;
        }

        queue <int> qu;
        for(int i=0;i<n;i++)
        {
            cin>>s;
            int s1=s[0]-'a';
            for(int j=0;j<n;j++)
            {
                manf[s1][j]=s[j+2]-'A';
            }
            qu.push(i);
        }
        for(int i=0;i<n;i++)
        {
            cin>>s;
            int s1=s[0]-'A';
            for(int j=0;j<n;j++)
            {
                womanf[s1][s[j+2]-'a']=j;
            }
        }

        while(!qu.empty())
        {
            int tem=qu.front();
            qu.pop();
            int mb=manf[tem][manp[tem]++];
            if(womanc[mb]==-1)
            {
                womanc[mb]=tem;
                manc[tem]=mb;
            }else if(womanf[mb][tem]<womanf[mb][womanc[mb]])
            {
                qu.push(womanc[mb]);
                manc[womanc[mb]]=-1;
                womanc[mb]=tem;
                manc[tem]=mb;

            }
            else
                qu.push(tem);
        }

        for(int i=0;i<26;i++)
        {
            if(people[i]==1)
            {
                //cout<<"i="<<i<<"manc[i]"<<manc[i]<<endl;
                printf("%c %c\n",i+'a',manc[i]+'A');
            }
        }
        if(T!=0)
        cout<<endl;


    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值