稳定婚姻问题:有n个男人,n个女人。每个人都有一个对异性的排名(1~n),假设男人主动追求女人,根据这些排名,我们需要将这些男女进行牵线,使得他们的婚姻稳定。
由于稳定不太好定义,我们定义一下不稳定。
不稳定婚姻:对于任意一个男人m, 假设其当前配偶为w, 若存在一个女人w1, 其当前配偶为 m1, 她在m 的排名中比 w 靠前,同时,m在 w1 的排名中比她现任丈夫 m1靠前,这时候我们称婚姻(m, w)为不稳定婚姻。
整个男女集合中不存在不稳定婚姻则这个集合为稳定婚姻集合。
那么,如何找到稳定婚姻呢? 算法步骤:
从第一个男人开始,找到其排名中最高的女人,
若这个女人单身,则
两人结合
否则若当前男人在这个女人的排名比其现任丈夫高,则
则当前男人与这个女人结合。这个女人原丈夫变为单身。
直到所有男人都找到配偶算法结束。
POJ 3487是一道稳定婚姻的入门题。因为需要处理的是字符串,所有这道题的存储结构稍微有点麻烦,用了两次哈希。
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<queue>
#include<vector>
using namespace std;
const int N = 32;
typedef vector<char>::iterator vc_i;
char male[N];
char female[N];
char in[128];
int hs[256];
int nhs[256];
int matched[256];
queue<int> que;
vector<char> G[N<<1];
int getLev(int f, char m)
{
int ret = 0;
for(vc_i i = G[f].begin(); i != G[f].end(); i++)
{
if(*i == m) break;
ret ++;
}
return ret;
}
int main()
{
int t;
// freopen("in.txt", "r", stdin);
scanf("%d", &t);
getchar();
while(t--)
{
int n;
scanf("%d", &n);
memset(hs, -1, sizeof(hs));
memset(matched, -1, sizeof(matched));
getchar();
for(int i = 0; i < n; i++){
scanf("%c", &male[i]);
getchar();
}
for(int i = 0; i < n; i++){
scanf("%c", &female[i]);
getchar();
}
int num = 0;
for(int i = 0; i < n; i++){
gets(in);
int j = 2;
int len = strlen(in);
if(hs[in[0]] == -1) {
G[num].clear();
hs[in[0]] = num;
nhs[num++] = in[0];
}
for(; j < len; j++)
G[hs[in[0]]].push_back(in[j]);
que.push(i);
}
for(int i = 0; i < n; i++){
gets(in);
int j = 2;
int len = strlen(in);
if(hs[in[0]] == -1) {
G[num].clear();
hs[in[0]] = num;
nhs[num++] = in[0];
}
for(; j < len; j++)
G[hs[in[0]]].push_back(in[j]);
}
while(!que.empty()){
int i = que.front();
que.pop();
for(vc_i j = G[i].begin(); j != G[i].end(); j++)
{
if(matched[hs[*j]] == -1)
{
matched[i] = hs[*j];
matched[hs[*j]] = i;
break;
}
else{
if(getLev(hs[*j], nhs[i]) < getLev(hs[*j], nhs[matched[hs[*j]]])){
que.push(matched[hs[*j]]);
matched[matched[hs[*j]]] = -1;
matched[i] = hs[*j];
matched[hs[*j]] = i;
break;
}
}
}
}
// sort(nhs, nhs + n); //根据题意是需要排序的,但没排序也过了。
for(int i = 0; i < n; i++)
printf("%c %c\n", nhs[i], nhs[matched[i]]);
puts("");
}
return 0;
}