poj3487 The Stable Marriage Problem

经典稳定婚姻问题

稳定婚姻问题(The Stable Marriage Problem)”大致说的就是100个GG和100个MM按照自己的喜欢程度给所有异性打分排序。每个帅哥都凭自己好恶给每个MM打分:我最爱a,其次爱b,再次爱c...每个帅哥打的分不同,你最爱的可能是我最讨厌的我最爱的可能是他不甚喜欢的。同样,每个美女也同样给每个帅哥打分。现在需要给他们搭配出100对新郎新娘,并且要保证所得到是稳定婚姻的搭配。那么,什么是不稳定的婚姻呢?所谓不稳婚姻是说, 比如说有两对夫妇(M1、F1)和(M2、F2),M1的老婆是F1,但他更爱F2;而F2的老公虽说是M2,但她更爱M1——这样的婚姻就是不稳婚姻,M1和F2理应结合,他们现在各自的婚姻都是错误。
那么,开始激动人心求婚过程啦
第一天上午, 所有的男生都向自己最爱的美眉求婚。下午,每个MM看看自己有没有收到, 收到了多少人的求婚。如果只收到一个男生的求婚,那么就和他订婚。如果收到多于一个GG的求婚,那么就和其中她最爱的那个男人订婚,同时把其他男人都拒掉。如果一个求婚都没有,不要着急,最后总会有的。晚上,检查一遍,如果所有MM都订婚了,OK,万事大吉,明天举行集体婚礼!
但如果还有人没有订婚,那么事情还没有完,第二天还得重复。
第二天上午,所有还没订婚的男生向自己次爱的美眉求婚(因为昨天已经被他们的最爱拒绝了)下午,每个MM再看一遍自己收到订婚的情况。如果她已经订婚了,但是又有一个她更爱的男人来向她求婚,那就把原来那个拒绝掉,再和这个更爱的男人订婚;如果还没订婚,那就和第一天的下午的处理一样。晚上再检查一遍,如果还是有人没有订婚,那第三天再重复。
第三天上午,所有没有订婚的GG,包括第一天订了第二天又被踹出来的(看来要有点忧患意识),再向还没有拒绝过他的MM中他最爱的那个求婚
......
如此周而复始,直到最后大家都订了婚,便一起结婚!哈哈,恭喜恭喜


 

 

代码如下,当时WA了好久T_T

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//a对应0号男,z对应25号男
//A对应0号女,Z对应25号女
struct T
{
    int love[26];//love[0],love[1],,,,,love[n-1]
    int person;//最终订婚的对象
    int yao;//已经邀请了0,1,2,,,,yao-1
}man[26];
struct U
{
    int love[26];//love[0],love[1],,,,,love[n-1]
    int person;//已订婚的对象
    int accept[26];//accept[0],,,,accept[num-1]
    int num;//有num个男士像她发出邀请
}woman[26];
int n;
int man_num[26];//man_num[0],man_num[1],,,,,man_num[n-1]
int woman_num[26];//woman_num[0],woman_num[1],,,,,woman_num[n-1]
bool check()
{
    int i;
    for(i=0;i<n;i++)
    {
        if(man[man_num[i]].person==-1)
        {
            return false;
        }
    }
    return true;
}
int main()
{
    int total;
    int i,j;
    scanf("%d",&total);
    while(total--)
    {
        scanf("%d",&n);//n个男的n个女的
        getchar();
        char ch;
        for(i=0;i<n;i++)
        {
            scanf("%c",&ch);
            man_num[i]=ch-'a';
            getchar();
        }
        for(i=0;i<n;i++)
        {
            scanf("%c",&ch);
            woman_num[i]=ch-'A';
            getchar();
        }
        char temp[100];
        int k;
        for(i=0;i<n;i++)
        {
            k=0;
            scanf("%s",temp);
            for(j=2;j<n+2;j++)
            {
                man[man_num[i]].love[k++]=temp[j]-'A';
            }
        }
        for(i=0;i<n;i++)
        {
            k=0;
            scanf("%s",temp);
            for(j=2;j<n+2;j++)
            {
                woman[woman_num[i]].love[k++]=temp[j]-'a';
            }
        }
        //完成输入
        for(i=0;i<n;i++)
        {
            man[man_num[i]].person=-1;
            man[man_num[i]].yao=0;
            woman[woman_num[i]].person=-1;
        }
        for(;;)//男士向他喜欢的yao人发出邀请
        {
            for(j=0;j<n;j++)
            {
                woman[woman_num[j]].num=0;
            }
            for(j=0;j<n;j++)//n个男士num[0],num[1],,,,num[n-1]
            {
                if(man[man_num[j]].person!=-1)//已经订婚就不发出邀请
                {
                    continue;
                }
                woman[man[man_num[j]].love[man[man_num[j]].yao]].accept[woman[man[man_num[j]].love[man[man_num[j]].yao]].num++]=man_num[j];
                man[man_num[j]].yao++;
            }
            //邀请发出完成一轮
            int l;
            for(j=0;j<n;j++)//woman_num[j]
            {
                int max=woman[woman_num[j]].person;
                if(max!=-1)
                {
                    for(k=0;k<n;k++)
                    {
                        if(woman[woman_num[j]].love[k]==max)
                        {
                            max=k;
                            break;
                        }
                    }
                }
                if(max==-1)
                {
                    max=26;
                }
                //max是已订婚对象在该女心中的地位,max越大,地位越低
                for(k=0;k<woman[woman_num[j]].num;k++)
                {
                    int tem=woman[woman_num[j]].accept[k];
                    for(l=0;l<n;l++)
                    {
                        if(woman[woman_num[j]].love[l]==tem)
                        {
                            tem=l;
                            break;
                        }
                    }
                    if(tem<max)//此时新的对象的地位高于原已订婚对象
                    {
                        if(max!=26)
                        {
                        man[woman[woman_num[j]].person].person=-1;
                        }
                        woman[woman_num[j]].person=woman[woman_num[j]].love[tem];
                        man[woman[woman_num[j]].person].person=woman_num[j];
                        max=tem;
                    }
                }
            }
            if(check())
            {
                break;
            }
        }
        for(i=0;i<n;i++)//man
        {
            printf("%c %c\n",man_num[i]+'a',man[man_num[i]].person+'A');
        }
        printf("\n");
    }
    return 0;
}

posted @ 2012-07-12 12:59  willzhang  阅读(556)  评论(0编辑  收藏  举报