ALG1:GS算法,稳定婚姻匹配问题

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;
}

 

 

仅供复习时整理参考,用于学习交流

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值