POJ 3487 The Stable Marriage Problem

125 篇文章 0 订阅

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.

稳定婚姻问题。
每次没有女友的男生在所有没有拒绝过他的女生中找一个最喜欢的表白,然后每个女生在自己的现男友和所有表白自己的男生中选一个最喜欢的接受。如果接受的是新男生的话,自己的前男友就被甩了。
可以证明【虽然我不会】,这种方法一定可以得到解,得到的解一定是可行解,而且这一解在所有解中对男生最优,对女生最劣。

#include<cstdio>
#include<cstring>
#define M(a) memset(a,0,sizeof(a))
int mrk[30][30],frk[30][30],cs[30][30],wf[30],hs[30],n,mnm[30],fnm[30],mnb[30],fnb[30];
bool ref[30][30];
void init()
{
    char s[50];
    int i,j,k,x,y,z;
    M(mrk);
    M(frk);
    M(cs);
    M(wf);
    M(hs);
    M(ref);
    M(mnm);
    M(fnm);
    M(mnb);
    M(fnb);
    scanf("%d",&n);
    for (i=1;i<=n;i++)
    {
        scanf("%s",s+1);
        mnm[i]=s[1]-'a'+1;
        mnb[s[1]-'a'+1]=i;
    }
    for (i=1;i<=n;i++)
    {
        scanf("%s",s+1);
        fnm[i]=s[1]-'A'+1;
        fnb[s[1]-'A'+1]=i;
    }
    for (i=1;i<=n;i++)
    {
        scanf("%s",s+1);
        x=mnb[s[1]-'a'+1];
        for (k=1;k<=n;k++)
          mrk[x][k]=fnb[s[k+2]-'A'+1];
    }
    for (i=1;i<=n;i++)
    {
        scanf("%s",s+1);
        x=fnb[s[1]-'A'+1];
        for (k=1;k<=n;k++)
          frk[x][k]=mnb[s[k+2]-'a'+1];
    }
}
void solve()
{
    int i,j,k,x,y,z;
    bool b;
    while (1)
    {
        b=0;
        M(cs);
        for (i=1;i<=n;i++)
          if (!wf[i])
          {
            b=1;
            for (j=1;j<=n;j++)
              if (!ref[i][mrk[i][j]])
              {
                cs[i][mrk[i][j]]=1;
                break;
              }
          }
        if (!b) return;
        for (i=1;i<=n;i++)
          for (j=1;j<=n;j++)
          {
            if (cs[frk[i][j]][i])
            {
                wf[frk[i][j]]=i;
                if (hs[i])
                {
                    wf[hs[i]]=0;
                    ref[hs[i]][i]=1;
                }
                hs[i]=frk[i][j];
                break;
            }
            if (frk[i][j]==hs[i]) break;
          }
        for (i=1;i<=n;i++)
          for (j=1;j<=n;j++)
            if (cs[i][j]&&hs[j]!=i)
              ref[i][j]=1;
    }
}
void prt()
{
    int i,j,k;
    for (i=1;i<=26;i++)
      if (mnb[i])
        printf("%c %c\n",i+'a'-1,fnm[wf[mnb[i]]]+'A'-1);
}
int main()
{
    int T,i;
    scanf("%d",&T);
    while (T--)
    {
        init();
        solve();
        prt();
        if (T) printf("\n");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值