ALG1:GS算法,稳定婚姻匹配问题
问题描述如下:
(详见NKU计算机上机课程辅助评测)
实现代码:
(此代码逻辑可通过全部测试样例)
由于代码有一段时间了,一下的展示代码是没有自己的输入数据的,如果需要改为想要使用的数据,应该重新输入矩阵M和矩阵W中的数据
#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
using namespace std;
int manNum = 5;
vector<vector<int>> M = {
{6, 5, 8, 9, 7},
{8, 6, 5, 7, 9},
{6, 9, 7, 8, 5},
{5, 8, 7, 6, 9},
{6, 8, 5, 9, 7}
};
vector<vector<int>> W = {
{4, 0, 1, 3, 2},
{2, 1, 3, 0, 4},
{1, 2, 3, 4, 0},
{0, 4, 3, 2, 1},
{3, 1, 4, 2, 0}
};
//男生编号:0, 1, 2, 3, 4
//女生编号:5, 6, 7, 8, 9
int main()
{
vector<vector<int>> wList(manNum, vector<int>(manNum)); //建立一个二维数组,储存女生心中的男生排序
for (int i = 0; i < manNum; i++)
for (int j = 0; j < manNum; j++)
wList[i][W[i][j]] = j; //[第几个女生][男生序号] = 男生在女生心中的位次
set<int> unDate; //用一个集合来储存非约会状态的男生
for (int i = 0; i < manNum; i++)
unDate.insert(i); //将所有男生放进去,初始化集合
vector<int> womanDate(manNum, -1), pos(manNum, 0); //womanDate[女生的序号] = 目前女生约会的男生序号(没有则是 -1)
//pos[男生序号] = 对应男生下一次需要邀请的女生在优先队列中的位置
/*
算法的主要思路:
①挑选一个男生(非约会状态的男生集合的第一个元素),进行②
②男生根据自己的女生优先列表,依次向后邀请女生,如果邀请的女生没有男伴了则邀请成功,进行④
如果邀请的女生有了男伴,则进行③
③接受邀请的女生,如果男伴,根据当前邀请的男生和原来已经接受的男伴在自己心中的排序,选择优先级更高的男生
如果接受当前的邀请,把原来的男伴重新移入非约会状态的集合
④将当前男生从非约会状态的集合中移除
不断循环,直到非约会男生的集合为空则跳出循环
*/
while (!unDate.empty())
{
set<int> ::iterator iter = unDate.begin(); //选择集合中的第一个男生
int man = *iter;
int woman = M[man][pos[man]] - manNum; //woman为当前男生想要邀请的女生
if (womanDate[woman] == -1) //该女生处于非约会状态
{
womanDate[woman] = man; //更改女生的约会状态
unDate.erase(iter); //将该男生从集合中移除
}
else //女生处于约会状态
{
if (wList[woman][man] < wList[woman][womanDate[woman]]) //当前男生优先
{
unDate.insert(womanDate[woman]); //将原来的男生重新加入集合
womanDate[woman] = man; //改变女生的约会状态
unDate.erase(iter); //将现在的男生从集合中移除
}
}
pos[man]++; //男生移向下一位
}
for (int i = 0; i < 5; i++)
cout << "man: " << womanDate[i] << " woman: " << i << endl; //配对结果
return 0;
}