HDU 1522(Marriage is Stable)

稳定婚姻问题,首先计算所有男人喜欢的女人的顺序和所有女人喜欢的男人的顺序。然后对于每个男人,按照其喜欢的女人的次序依次和女人匹配,分为两种情况:

  1. 女人未匹配,则该男人和女人匹配;
  2. 女人已匹配,如果相较于目前匹配的男人,该女人更喜欢该男人,则该男人和女人匹配,该女人之前匹配的男人置为未匹配状态。

重复上述操作,直到所有男人和女人都匹配。

#include <iostream>
#include <string>
#include <map>
#include <cstring>
using namespace std;
const int MAXN = 505;

string boy[MAXN], girl[MAXN]; //姓名
map<string, int> mpB, mpG; //姓名-编号
int rankB[MAXN][MAXN]; //编号为i的男人的第j个喜欢的女人的编号
int rankG[MAXN][MAXN]; //编号为i的女人对编号为j的男人的排名
int matchB[MAXN], matchG[MAXN]; //匹配情况
int num[MAXN]; //编号为i的男人目前判断第几喜欢的女人
int n; //男女人数

//计算男人和女人喜欢的顺序
void getRank()
{
	string s;
	for (int i = 1; i <= n; i++)
	{
		cin >> s;
		boy[i] = s;
		mpB[s] = i;
		for (int j = 1; j <= n; j++)
		{
			cin >> s;
			if (mpG[s] == 0)
			{
				girl[j] = s;
				mpG[s] = j;
				rankB[i][j] = j;
			}
			else
				rankB[i][j] = mpG[s];
		}
	}
	for (int i = 1; i <= n; i++)
	{
		cin >> s;
		int number = mpG[s];
		for (int j = 1; j <= n; j++)
		{
			cin >> s;
			rankG[number][mpB[s]] = j;
		}
	}
}

//计算匹配情况
void getMatch()
{
	for (int i = 1; i <= n; i++)
	{
		num[i] = 1;
	}
	bool flag = true;
	while (flag)
	{
		flag = false;
		for (int i = 1; i <= n; i++)
		{
			if (matchB[i] == 0)
			{
				int number = rankB[i][num[i]++];
				if (matchG[number] == 0)
				{
					matchB[i] = number;
					matchG[number] = i;
				}
				else if (rankG[number][i] < rankG[number][matchG[number]])
				{
					matchB[matchG[number]] = 0;
					matchB[i] = number;
					matchG[number] = i;
				}
				flag = true;
			}
		}
	}
}

int main()
{
	while (cin >> n)
	{
		memset(rankB, 0, sizeof(rankB));
		memset(rankG, 0, sizeof(rankG));
		memset(matchB, 0, sizeof(matchB));
		memset(matchG, 0, sizeof(matchG));
		mpB.clear();
		mpG.clear();

		getRank();
		getMatch();
		
		for (int i = 1; i <= n; i++)
			cout << boy[i] << " " << girl[matchB[i]] << endl;
		cout << endl;		
	}
	return 0;
}

 

继续加油。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值