zoj 1576 Marriage is Stable

稳定婚姻问题

对于稳定婚姻问题,必然存在一个解,所以此题不用考虑无解的情况。用Gale-Shapley+map可以直接搞定。

注意:男女名字可能相同。

Gale-Shapley算法详解:

http://wenku.baidu.com/view/2b5a4c7a1711cc7931b7164a.html

 

#include <iostream>
#include <cstdio>
#include <map>
using namespace std;

#define MAX 0x3fffffff
#define MAXN 601
map<string,int>human,human1;
map<int,string>rehuman,rehuman1;

int liman[MAXN][MAXN], liblady[MAXN][MAXN], libladyValue[MAXN][MAXN];
int man[MAXN],lady[MAXN];
int Stack[MAXN*2], top;

int main()
{
    int n, k, r;
    char s1[10000],s2[10000];
    while(~scanf("%d",&n)){
        human.clear();
        human1.clear();
        rehuman.clear();
        rehuman1.clear();
        k = r = 0;
        scanf("%s",s1);
        human[s1] = k;
        rehuman[k++] = s1;
        for(int j = 0; j < n; j++){
                scanf("%s",s2);
                human1[s2] = r;
                rehuman1[r++] = s2;
                liman[human[s1]][j] = human1[s2];
        }
        for(int i = 1; i < n; i++){
            scanf("%s",s1);
            human[s1] = k;
            rehuman[k++] = s1;
            for(int j = 0; j < n; j++){
                scanf("%s",s2);
                liman[human[s1]][j] = human1[s2];
            }
        }
        for(int i = 1; i <= n; i++){
            scanf("%s",s1);
            for(int j = 0; j < n; j++){
                scanf("%s",s2);
                liblady[human1[s1]][j] = human[s2];
            }
        }
        for(int i = 0; i < MAXN; i++){
            lady[i] = MAX;
            man[i] = 0;
        }
        for(int i = 0; i < n ; i++){
            for(int j = n,t = 0; j >= 0; j--,t++){
                libladyValue[i][liblady[i][j]] = t;
            }
        }
        k = 0;top = -1;
        while(k < n){
            Stack[++top] = k++;
        }
        /*for(int i = 0; i < n; i++){
            printf("%d ",Stack[i]);
        }
        putchar('\n');
        putchar('\n');

        for(int i = 0; i < n; i++){
            for(int j = 0; j < n; j++)
            printf("liman[%d][%d] = %d ",i,j,liman[i][j]);
            putchar('\n');
        }
        putchar('\n');
        for(int i = 0; i < n ; i++){
            for(int j = 0; j < n; j++){
                printf("%d ",libladyValue[i][j]);
            }
            putchar('\n');
        }
3
Albert Laura Nancy Marcy
Brad Marcy Nancy Laura
Chuck Laura Marcy Nancy
Laura Chuck Albert Brad
Marcy Albert Chuck Brad
Nancy Brad Albert Chuck
3
A L N M
B M N L
C L M N
L C A B
M A C B
N B A C

        */

        while(top >= 0){
            int t = liman[Stack[top]][man[Stack[top]]];
            if(libladyValue[t][lady[t]] < libladyValue[t][Stack[top]]){
                int v = lady[t];
                man[v]++;
                lady[t] = Stack[top--];
                if(v != MAX){
                    Stack[++top] = v;
                }
            }
            else man[Stack[top]]++;

        }
        for(int i = 0; i < n; i++){
            k = man[i];

            cout<<rehuman[i]<<" "<<rehuman1[liman[i][k]]<<endl;
        }

    }
    return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值