稳定婚姻问题:
- N男和N女的匹配问题,两两配对。
- 很多BLOG以及稳定婚姻算法的设定都是男生追女生,此处全部改掉。
- 每一个女生对所有的男生有一个排序,这个女生会最先去追排在第一位的男生,如果这个男的把这个女的拒绝了,那么这个女的就回去选在排在第二位的男生,如果这个男生还把她给拒绝了,那就依次类推。
- 每一个男生对所有的女生有一个评分(每个男人对每个女生的评分不一样,因人而异),一个男生希望评分高的女生向自己表白,如果别人有人了,那就评分低点的也行,以此类推。
- 不稳定婚姻因素设定:如果一个男生有女朋友,但是此时来个一个在男生心中评分更高(更完美)的女生向男生表白。此时这个男生就会放弃现在现有的女朋友去和分值更高的这个女生在一起。
算法思想:
- 根据女生对男生的排序进行遍历
- 如果当前男生,拒绝过该女生,那么女生就要换一个分值稍低的男生
- 如果当前男生,没有拒绝过该女生,并且该男生没有女朋友,“暂时”配对成功
- 如果当前男生,没有拒绝过该女生,并且该男生有女朋友,如果现在表白的这个女生的分值高于男生的现女友,那么男生为了“稳定的婚姻关系”需要抛弃现女友,选择和这个表白的女孩在一起,然后再将被分手的女孩设置为未匹配状态。
- 算法一直到所有女生配对成功为止。
配题:HDU 1522
题意:配对问题,给 n 对男生女生,姓名,前 n 行,每行第一个人名表示男生,后 n 个人名表示女生,顺序是男生愿意从左向右追,后 n 行,每行第一个人名表示女生,后 n 个人名表示男生,顺序是女生认为左边的男生比右边的男生分值更高。然后输出一种稳定的婚姻关系(任意一种即可)。
思想:这个题目难点感觉不在稳定婚姻算法,倒是在人名的映射。(我没有考虑,男生和女生重名的问题)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<map>
using namespace std;
const int maxn = 505;
int n;
int bgorder[maxn][maxn];
int gbscore[maxn][maxn];
int bg[maxn], gb[maxn];
bool vis[maxn][maxn]; // man has been refused by woman
map<int, string>itosmap;
map<string, int>stoimap;
void init()
{
itosmap.clear();
stoimap.clear();
memset(bgorder, 0, sizeof(bgorder));
memset(gbscore, 0, sizeof(gbscore));
}
void stable_marriage()
{
queue<int>Mq;
while (!Mq.empty()) Mq.pop();
memset(vis, false, sizeof(vis));
memset(gb, -1, sizeof(gb));
for (int i = 1; i <= n; i++)
{
Mq.push(i);
}
while (!Mq.empty())
{
int man = Mq.front();
Mq.pop();
for (int i = 1; i <= n; i++)
{
int girl = bgorder[man][i];
if (vis[man][girl])
{
continue;
}
if (gb[girl] == -1)
{
gb[girl] = man;
bg[man] = girl;
break;
}
else
{
if (gbscore[girl][gb[girl]] < gbscore[girl][man])
{
Mq.push(gb[girl]);
gb[girl] = man;
bg[man] = girl;
break;
}
}
}
}
}
int main()
{
while (cin>> n)
{
int boy_id = 1;
int girl_id = n+1;
for (int i = 1; i <= n; i++)
{
char boyname[20];
cin>> boyname;
if (!stoimap[boyname])
{
stoimap[boyname] = boy_id;
itosmap[boy_id++] = boyname;
}
for (int j = 1; j <= n; j++)
{
char girlname[20];
cin>> girlname;
if (!stoimap[girlname])
{
stoimap[girlname] = girl_id;
itosmap[girl_id++] = girlname;
}
bgorder[stoimap[boyname]][j] = stoimap[girlname]-n;
}
}
for (int i = 1; i <= n; i++)
{
char girlname[20];
cin>> girlname;
for (int j = 1; j <= n; j++)
{
char boyname[20];
cin>> boyname;
gbscore[stoimap[girlname]-n][stoimap[boyname]] = n+1-j;
}
}
stable_marriage();
for (int i = 1; i <= n; i++)
{
cout<< itosmap[i]<< " "<< itosmap[bg[i]+n]<< endl;
}
cout<< endl;
}
return 0;
}