结婚匹配问题

问题大概是这样:有一个社团里有n个女生和n个男生,每位女生按照她的偏爱程度将男生排序,同时每位男生也按照自己的偏爱程度将女生排序。然后将这n个女生和n个男生配成完备婚姻。

如果存在两位女生A和B,两位男生a和b,使得A和a结婚,B和b结婚,但是A更偏爱b而不是a,b更偏爱A而不是B,则这个婚姻就是不稳定的,A和b可能背着别人相伴而走,因为他俩都认为,与当前配偶比起来他们更偏爱各自的新伴侣。

如果完备婚姻不是不稳定的,则称其是稳定的。通过证明,可以得到每一个n女n男的社团,都存在稳定婚姻的结论。但是这种情况只在异性的社团中存在。也就是说在同性的社团里面,稳定婚姻的存在性将不再被保证。

Gale-Shapley 算法

while  存在男人m是自由的且还没对每个女人都求过婚
      选择这个男人m
                令w是m的优先表中还没求过婚的最高排名的女人
        if  w是自由的  
            (m,w)变成约会状态
        else  w当前与m1约会
              if  w更偏爱m1而不爱m
                                  m保持自由
              else    w更偏爱m而不爱m1
                                        (m,w)变成约会状态
                    m1变成自由
              endif
                  endif
endwhile

下面是关于 稳定婚姻问题 的题目:

1. ZJU 1576 Marriage is Stable

AC代码如下:

#include<iostream>
#include<cstring>
#include<string>
#include<map>
using namespace std;

int nb, ng, n;
map<string, int> boy;
map<string, int> girl;
string boymk[510], girlmk[510];

int a[510][510], rank[510][510], pose[510];
int vm1[505], vm2[505], input[510];

int find_boy(string s){
    if (boy.count(s) == 0){
        boymk[nb] = s;
        boy[s] = nb;
        nb++;
    }
    return boy[s];
}

int find_girl(string s){
    if (girl.count(s) == 0){
        girlmk[ng] = s;
        girl[s] = ng;
        ng++;
    }
    return girl[s];
}

int main(){
    int i, j, v1, v2, u, v;
    string s;
    while (cin >> n){
        nb = ng = 0;
        boy.clear();  girl.clear();
        for (i = 0; i < n; i++){
            cin >> s;
            v1 = find_boy(s);
            input[i] = v1;
            for (j = 0; j < n; j++){
                    cin >> s;
                    v2 = find_girl(s);
                    a[v1][j] = v2;
            }
        }
        for (i = 0; i < n; i++){
            cin >> s;
            v1 = find_girl(s);
            for (j = 0; j < n; j++){
                    cin >> s;
                    v2 = find_boy(s);
                    rank[v1][v2]=j;
            }
        }
        memset(pose, 0, sizeof(pose));
        memset(vm1, -1, sizeof(vm1));
        memset(vm2, -1, sizeof(vm2));
        while(1){
            for (i = 0; i < n; i++) if (vm1[i] == -1) break;
            if (i == n) break;
            u = i;
            v = a[u][pose[u]++];
            if (vm2[v] == -1){
                    vm2[v] = u;
                    vm1[u] = v;
            }
            else if (rank[v][vm2[v]] > rank[v][u]){
                    vm1[vm2[v]] = -1;
                    vm2[v] = u;
                    vm1[u] = v;
            }
        }
        for (i = 0; i < n; i++)
                cout << boymk[input[i]] << ' ' << girlmk[vm1[input[i]]] << endl;
        cout << endl;
    }
    return 0;
}



你可能感兴趣的:(结婚匹配问题)