The Stable Marriage Problem

The Stable Marriage Problem

Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 64 Accepted Submission(s): 40
 
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
 
 
Source
Southeastern Europe 2007
 
Recommend
lcy
 
/*
题意:给你n个男生,和n个女生,给出它们心里的对象的排名,看能不能形成稳定的婚姻,所谓稳定的婚姻,假如a和b
    匹配,c和d匹配,如果a认为d比b好,同时d也认为a比c好,那么ad就有可能私奔。这样就形成了不稳定的婚姻
    
初步思路:稳定婚姻问题,稳定婚姻问题跟二分匹配问题相似,解法都是延迟匹配方案,将所有的男生放入队列中,如
    然后遍历,如果当前男生没有女朋友,就从他的心仪对象中从高到低找女朋友,如果这个女生有男朋友了,就看看
    这个女生更喜欢哪个男生。如此往下进行模拟,直到所有的男生都找到了自己的女朋友
    
#错误:日了狗了,wa了无数遍

#改正:找到了错误了!题目给的名字不一定是字典序,但是要按照字典序输出!!!!!!
*/
#include<iostream>
#include<string>
#include<string.h>
#include<map>
#include<stdio.h>
using namespace std;
/***************************稳定婚姻模板***************************/
int n;
int gp_boy[100][100];//用来存储i号男生喜欢的女生
int gp_girl[100][100];//用来存储i号女生喜欢的男生
int boy[100];//用来存储i号男生的女朋友
int girl[100];//用来存储i号女生的男朋友
int pos[100][100];//用来从存储男神喜欢的第i个女生是谁
int rankl[100];//用来标记男生追到了自己喜欢的第几个女生
map<char,int>mp_boy,mp_girl;//用来给男生女生的名字编号
char sboy[100],sgirl[100];//用来储存编号i男生的名字
char name[100];
int t;
int in[100];//用来标记名字
void Gale_Shapley()
{
    memset(boy,0,sizeof(boy));
    memset(girl,0,sizeof(girl));
    for(int i=1; i<=n; i++) 
        rankl[i]=1;
    while(true)
    {
        int flag=0;
        for(int i=1; i<=n; i++)
        {
            if(boy[i]) //如果这个男生有女朋友了
                continue;
            int g=pos[i][rankl[i]];
            if(!girl[g]){//这个女上也没有男朋友
                boy[i] = g, girl[g] = i;
            }
            else{
                if(gp_girl[g][i]<gp_girl[g][girl[g]]){//如果有男朋友了,就看看这个女生更喜欢哪个
            //男生就和哪个男生好
                    boy[girl[g]] = 0, girl[g] = i, boy[i] = g;
                    rankl[girl[g]]++;
                }else {
                    rankl[i]++;
                }
                flag = 1;
            }
        }
        if(flag==0) break;
    }
}
void init(){
    mp_boy.clear();
    mp_girl.clear();
    memset(in,0,sizeof in);
}
/***************************稳定婚姻模板***************************/
int main(){
    // freopen("in.txt","r",stdin);
    scanf("%d",&t);
    for(int ca=0;ca<t;ca++){
        scanf("%d",&n);
        init();
        if(ca) 
            printf("\n");
        for(int i=0;i<n;i++){
            scanf("%s",&name[i]);
            mp_boy[name[i]]=i+1;
            in[name[i]-'a']=1;//标记这个名字有人了
            sboy[i+1]=name[i];
        }//处理男生名字输入
        
        for(int i=0;i<n;i++){
            scanf("%s",&name[i]);
            mp_girl[name[i]]=i+1;
            sgirl[i+1]=name[i];
        }//处理女生名字输入
        
        
        for(int i=0;i<n;i++){
            scanf("%s",&name);
            int tmpb=mp_boy[name[0]];//tmpb男生的暗恋对象
            for(int j=2;j<=n+1;j++){
                int tmpg=mp_girl[name[j]];
                
                gp_boy[tmpb][tmpg]=j-1;//男生tmpb喜欢女生tmpg排第j-1
                pos[tmpb][j-1]=tmpg;
            }
        }//处理男生对象输入
        
        for(int i=0;i<n;i++){
            scanf("%s",&name);
            int tmpg=mp_girl[name[0]];//tmpg女生的暗恋对象
            for(int j=2;j<=n+1;j++){
                int tmpb=mp_boy[name[j]];
                
                gp_girl[tmpg][tmpb]=j-1;//女生tmpg喜欢男生tmpb排第j-1
            }
        }//处理女生对象输入
        Gale_Shapley();
        for(int i=0;i<=26;i++){
            if(in[i]){
                printf("%c %c\n",i+'a',sgirl[boy[mp_boy[i+'a']]]);
            }
        }
    }
    return 0;
}

 

posted @ 2017-02-21 13:58  勿忘初心0924  阅读(1034)  评论(0编辑  收藏  举报