• Ladies' Choice UVALive


    /**
    题目: Ladies' Choice UVALive - 3989
    链接:https://vjudge.net/problem/UVALive-3989
    题意:稳定婚姻问题
    思路:
    gale_shapley算法,参考文档:https://wenku.baidu.com/view/7aa841f2fab069dc502201cb.html
    
    */
    
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <queue>
    using namespace std;
    const int MAXN = 1005;
    const int INF = 0x3f3f3f3f;
    
    int blove[MAXN][MAXN];///存储女生编号 排在前面的女生编号越喜欢 !!!和glove[][]是不同的。
    int glove[MAXN][MAXN];///表示第i个女生对第j个男生的的好感度 数值越大越喜欢
    int boy[MAXN];///男生当前选择的女生。如果为-1,表示还没有选择。
    int girl[MAXN];///女生当前选择的男生。如果为-1,表示还没有选择。
    int boyrank[MAXN];///维护男生最中意的女生编号(排除已经拒绝他的女生之后)初始为1表示最喜欢最前面的那一个。
    int N;
    
    void gale_shapley()///稳定婚姻问题   男生主动找女生 男生找的是最喜欢的,女生找的是稳定的最差的。交换数据可以反之。
    {
        memset(girl, -1, sizeof girl);
        memset(boy, -1, sizeof boy);
        for(int i = 1; i <= N; i++) boyrank[i] = 1;
        int cnt = 0;
        while(cnt<N){///当cnt==N表示N个男生都选好了。
            cnt = 0;
            for(int i = 1; i <= N; i++){///所有男生向自己最中意的女生表白。
                if(boy[i]!=-1){
                    cnt++;
                    continue;///该男生已经选好了。暂时不用再选。
                }
    
                int bestgirl = blove[i][boyrank[i]];
    
                if(girl[bestgirl]==-1){///该女生没有选择别人。
                    girl[bestgirl] = i;
                    boy[i] = bestgirl;
                }else
                {
                    if(glove[bestgirl][i]>glove[bestgirl][girl[bestgirl]]){
                        boyrank[girl[bestgirl]]++;///该女生找到更好的,被抛弃的男的要重新选择。更新男生最中意的女生。
                        boy[girl[bestgirl]] = -1;///被抛弃的男生没有选择的女生了。
                        girl[bestgirl] = i;
                        boy[i] = bestgirl;
                    }else///女生坚持自己已经选过的,当前男生被拒绝。
                    {
                        boyrank[i]++;
                    }
                }
            }
        }
    }
    int main()
    {
        int T, n;
        cin>>T;
        while(T--)
        {
            scanf("%d",&n);
            N = n;
            int x;
            for(int i = 1; i <= N; i++){
                for(int j = 1; j <= N; j++){
                    scanf("%d",&x);
                    blove[i][j] = x;
                }
            }
            for(int i = 1; i <= N; i++){
                for(int j = 1; j <= N; j++){
                    scanf("%d",&x);
                    glove[i][x] = N-j;
                }
            }
            gale_shapley();
            for(int i = 1; i <= N; i++){
                printf("%d
    ",boy[i]);
            }
            if(T>0){
                printf("
    ");
            }
        }
        return 0;
    }

    模板:

    const int MAXN = 1005;
    const int INF = 0x3f3f3f3f;
    
    int blove[MAXN][MAXN];///存储女生编号 排在前面的女生编号越喜欢 !!!和glove[][]是不同的。
    int glove[MAXN][MAXN];///表示第i个女生对第j个男生的的好感度 数值越大越喜欢
    int boy[MAXN];///男生当前选择的女生编号。如果为-1,表示还没有选择。
    int girl[MAXN];///女生当前选择的男生。如果为-1,表示还没有选择。
    int boyrank[MAXN];///维护男生最中意的女生编号(排除已经拒绝他的女生之后)初始为1表示最喜欢最前面的那一个。
    int N;
    
    void gale_shapley()///稳定婚姻问题   男生主动找女生 男生找的是最喜欢的,女生找的是稳定的最差的。交换数据可以反之。
    {
        memset(girl, -1, sizeof girl);
        memset(boy, -1, sizeof boy);
        for(int i = 1; i <= N; i++) boyrank[i] = 1;
        int cnt = 0;
        while(cnt<N){///当cnt==N表示N个男生都选好了。
            cnt = 0;
            for(int i = 1; i <= N; i++){///所有男生向自己最中意的女生表白。
                if(boy[i]!=-1){
                    cnt++;
                    continue;///该男生已经选好了。暂时不用再选。
                }
    
                int bestgirl = blove[i][boyrank[i]];
    
                if(girl[bestgirl]==-1){///该女生没有选择别人。
                    girl[bestgirl] = i;
                    boy[i] = bestgirl;
                }else
                {
                    if(glove[bestgirl][i]>glove[bestgirl][girl[bestgirl]]){
                        boyrank[girl[bestgirl]]++;///该女生找到更好的,被抛弃的男的要重新选择。更新男生最中意的女生。
                        boy[girl[bestgirl]] = -1;///被抛弃的男生没有选择的女生了。
                        girl[bestgirl] = i;
                        boy[i] = bestgirl;
                    }else///女生坚持自己已经选过的,当前男生被拒绝。
                    {
                        boyrank[i]++;
                    }
                }
            }
        }
    }
  • 相关阅读:
    nginx安装:linux环境下安装包安装
    Effective C++
    Win32 Msg
    C++ 17
    Win32 Threads
    Exceptional C++
    C++11
    STL 分类
    C++类型转换
    红黑树
  • 原文地址:https://www.cnblogs.com/xiaochaoqun/p/7209569.html
Copyright © 2020-2023  润新知