HDU 1522 Marriage is Stable【稳定婚姻】

题意: 有 N  个男生和 N 个女生,已知每个男生对每个女生的喜欢程度,和每个女生对每个男生的喜欢程度。

         找到一种搭配方式使得总的满意程度最高。

稳定婚姻解法:

          如果男A与女C匹配,男B与女D 匹配,但是A更喜欢D,D更喜欢A,那么这个婚姻就不是稳定的。稳定婚姻问题的算法步骤大致如下:(男士优先)

        1.男士先选择自己最爱的人去求婚,如果有多个男士的最爱相同,那么女士就选择更爱的那位男士,那么其他的男士在这次求婚中失败。

        2.上次求婚失败的男士再选择自己次爱的女士进行求婚,如果这位女士没有匹配男士,那么这两个人就进行匹配,如果这位女士有匹配的男士,但是如果这位女士更喜欢这位正在求婚的男士,那么这位女士就可以抛弃原有的男士而与这位她更爱的男士匹配。而原有的男士在这次匹配中失败。

        3.上次求婚失败的男士(包括被女士抛弃的男士)再次选择自己次爱的女士求婚,知道所有的男士与女士全部匹配则结束。

       次算法被证明必定存在解,刚才所写的步骤是基于男士优先的。如果是女士向男士求婚,那么就是基于女士优先的,算法步骤和上面的基本相同,只要将男女调换就可以了。

 

#include<stdio.h>
#include<string.h>
#include<string>
#include<map>
#include<iostream>
#include<algorithm>
#define maxn 555
#define clr(x)memset(x,0,sizeof(x))
using namespace std;
int tot;
int n;
int b[maxn][maxn];
int g[maxn][maxn];
int by[maxn],gl[maxn];
int r[maxn];
char s[100];
string bo[maxn],gi[maxn];
int main()
{
    int bn,gn,t,flag,i,j,f;
    while(scanf("%d",&n)!=EOF)
    {
        f=0;
        getchar(); 
        gn=1;
        clr(b);
        clr(g);
        for(i=1;i<=n;i++)r[i]=1;
        map<string,int>boy,girl;
          boy.clear(),girl.clear();
        tot=1;
        for(i=1;i<=n;i++)
        {
            scanf("%s",s);
            boy[s]=i;
            bo[i]=s;
            for(j=1;j<=n;j++)
            {
                scanf("%s",s);
                if(!girl[s])
                {
                    girl[s]=j;
                    gi[j]=s;
                    b[i][j]=j;
                }
                else b[i][j]=girl[s];
            }
        }
        for(i=1;i<=n;i++)
        {
            scanf("%s",s);
            t=girl[s];
            for(j=1;j<=n;j++)
            {
                scanf("%s",s);
                g[t][boy[s]]=n-j;
            }
        }
        clr(by);  clr(gl);
        while(1)
        {
            flag=1;
            for(i=1;i<=n;i++)
                if(!by[i])
                {
                    t=b[i][r[i]++];
                    if(!gl[t])
                    {
                        by[i]=t;
                        gl[t]=i;
                    }
                    else if(g[t][gl[t]]<g[t][i])
                    {
                        by[gl[t]]=0;
                        gl[t]=i;
                        by[i]=t;
                    }
                    flag=0;
                }
            if(flag)
                break;
        }
        for(i=1;i<=n;i++)
            cout<<bo[i]<<' '<<gi[by[i]]<<endl;
        printf("\n");
    }
    return 0;
}

 

 

 

 

posted @ 2012-08-04 18:56  'wind  阅读(524)  评论(0编辑  收藏  举报