HDU 1522 Marriage is Stable 稳定婚姻问题

Marriage is Stable

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 619    Accepted Submission(s): 355
Special Judge


Problem Description
Albert, Brad, Chuck are happy bachelors who are in love with Laura, Marcy, Nancy. They all have three choices. But in fact, they do have some preference in mind. Say Albert, he likes Laura best, but that doesn't necesarily mean Laura likes him. Laura likes Chuck more than Albert. So if Albert can't marry Laura, he thinks Nancy a sensible choice. For Albert, he orders the girls Laura > Nancy > Marcy.

For the boys:
Albert: Laura > Nancy > Marcy
Brad: Marcy > Nancy > Laura
Chuck: Laura > Marcy > Nancy

For the girls:
Laura: Chuck > Albert > Brad
Marcy: Albert > Chuck > Brad
Nancy: Brad > Albert > Chuck

But if they were matched randomly, such as
Albert <-> Laura
Brad <-> Marcy
Chuck <-> Nancy

they would soon discover it's not a nice solution. For Laura, she likes Chuck instead of Albert. And what's more, Chuck likes Laura better than Nancy. So Laura and Chuck are likely to come together, leaving poor Albert and Nancy.

Now it's your turn to find a stable marriage. A stable marriage means for any boy G and girl M, with their choice m[G] and m[M], it will not happen that rank(G, M) < rank(G, m[G])and rank(M, G) < rank(M, m[M]).
 
Input
Each case starts with an integer n (1 <= n <= 500), the number of matches to make.
The following n lines contain n + 1 names each, the first being name of the boy, and rest being the rank of the girls.
The following n lines are the same information for the girls.
Process to the end of file.
 
Output
If there is a stable marriage, print n lines with two names on each line. You can choose any one if there are multiple solution. Print "Impossible" otherwise.
Print a blank line after each test.

Sample Input
  
  
3 Albert Laura Nancy Marcy Brad Marcy Nancy Laura Chuck Laura Marcy Nancy Laura Chuck Albert Brad Marcy Albert Chuck Brad Nancy Brad Albert Chuck
 
Sample Output
  
  
Albert Nancy Brad Marcy Chuck Laura
/*
HDU 1522 稳定婚姻问题 
有N个男生和N个女生,已知每个男生对每个女生的喜欢程度,和每个女生对每个男生的喜欢程度。
找到一种搭配方式使得总的满意程度最高。

稳定婚姻解法:
    如果男A与女C匹配,男B与女D匹配,但是A更喜欢D,D更喜欢A,那么这个婚姻就不是稳定的。
	
Gale-Shapley算法:
先对所有男士进行落选标记,称其为自由男。当存在自由男时,进行以下操作:
    ① 每一位自由男在所有尚未拒绝她的女士中选择一位被他排名最优先的女士;
    ② 每一位女士将正在追求她的自由男与其当前男友进行比较,选择其中排名优先的男士作为其男友,
即若自由男优于当前男友,则抛弃前男友;否则保留其男友,拒绝自由男。
    ③ 若某男士被其女友抛弃,重新变成自由男。

error C2679: 二进制“<<” : 没有找到接受“<未知>”类型的右操作数的运算符(或没有可接受的转换)
表示string头文件 未加 
*/
#include<iostream>
#include<stdio.h>
#include<string>
#include<map>
using namespace std;
#define N 501
string boyNum[N],girlNum[N];
map<string,int>boyStr,girlStr;
int b[N][N],g[N][N];//表示男生喜爱的女生 排序 
int bM[N],gM[N];//男生结婚,配对的女生 
int rank[N];//男生喜欢的女生 i从1开始递增 1最喜欢 
int n;

void init()
{
	boyStr.clear();//名字存储 string-i
	girlStr.clear();
	
	memset(boyNum,0,sizeof(boyNum));//名字存储 i-string 
	memset(girlNum,0,sizeof(girlNum));
	
	memset(b,0,sizeof(b));//每个人喜欢的人的排列 
	memset(g,0,sizeof(b));
	
	memset(bM,0,sizeof(bM));//配对 
	memset(gM,0,sizeof(gM));
	
	for(int i=1;i<=n;i++)//初始化 男生开始选择最喜欢的 
		rank[i]=1;
	
}
int main()
{
	int i,j,t,flag;
	char str[100];
	
	while(scanf("%d",&n)!=EOF)
	{
		init(); 
		for(i=1;i<=n;i++)
		{
			scanf("%s",str);
			boyStr[str]=i;//将名字与序号对应 string-i
			boyNum[i]=str;// i-string
			for(j=1;j<=n;j++)
			{
				scanf("%s",str);
				if(!girlStr[str])
				{
					girlStr[str]=j;//将名字与序号对应 string-i 
					girlNum[j]=str;//i-string
					b[i][j]=j;//表示男生喜爱 对应的女生序号 j越小越喜欢 递增 
				}
				else
					b[i][j]=girlStr[str];
			}
		}
		
		for(i=1;i<=n;i++)
		{
			scanf("%s",str);
			t=girlStr[str];//女生名字对应的序号
			for(j=1;j<=n;j++)
			{
				scanf("%s",str);
				g[t][boyStr[str]]=n-j;//女生喜欢的男生 对应数字越大越喜欢 
			}
		} 
		
		while(1)
		{
			flag=1;
			for(i=1;i<=n;i++)
			{
				if(!bM[i])//如果i个男生未配对 
				{
					t=b[i][rank[i]++];//选择当前女生配对,rank从1开始递增 最喜欢开始 
					if(!gM[t])//该女生也没配对 
					{
						bM[i]=t;
						gM[t]=i;
					}
					else if(g[t][gM[t]]<g[t][i])//该女生配对了,但是当前的男友没现在的喜欢 
					{
						bM[gM[t]]=0;//前男友为自由男 
						bM[i]=t;
						gM[t]=i;
					}
					flag=0;//若所有bM[i]=1,都结婚,falg=1; 
				}
			}
			if(flag)
				break;
		}
		
		for(i=1;i<=n;i++)
			cout<<boyNum[i]<<" "<<girlNum[bM[i]]<<endl;
		printf("\n");
	}
	return 0;
} 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值