zoj 1567 Marriage is Stable

博客探讨了稳定婚姻问题,给定男生和女生的偏好列表,寻找稳定的婚姻匹配。通过算法解析,解释如何以女生为主导进行匹配,确保每个男生都能找到至少一个他们喜欢的女生,同时女生也会选择最喜欢自己的男生。最后,提供了问题的代码实现。
摘要由CSDN通过智能技术生成

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.


<b< dd="">

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.


<b< dd="">

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


<b< dd="">

Sample Output

Albert Nancy
Brad Marcy

Chuck Laura

题目大意:给出几个男孩喜欢几个女孩的程度,再给出女孩喜欢男孩的程度,现在需要对着几个男孩还有女孩进行配对,要求达到皮队合适。

解题思路:稳定婚姻问题,该问题按照思路大致是这样:以女生为主,进行匹配。首先,根据男生都向自己喜欢的女生进行求婚,每个女生男生在向自己求婚的男生中,选取一个自己最喜欢的,如果只有一个,那就选择这个男生。之后如果还有男生是单身的,再想自己次要喜欢的女生进行求婚,如果这个当前女生已经有了对象,并且当前女生对目前对象喜欢程度不如现在求婚的,那该女生可以换对象,她之前的对象就成了单身。就这样一次进行匹配,因为男女生人数相等,这样进行匹配的最终结果是每个男生都有一个女生,每个女生也都有一个男生。并且匹配最坏的情况下,男生也能选择一个最喜欢自己的女生。

代码:

#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<map>
#include<algorithm>
using namespace std;
#include<queue>
int man[510][510];
int G[510][510];
int book[510][510];
int a[510];
int b[510];
string s1[510];
string s2[510];
char s0[110];
int main()
{
	int i,j,k,x,y,z,v,n;
	int d[510];
	while(scanf("%d",&n)!=EOF)
	{
	    map<string,int> s3,s4;
	    memset(a,0,sizeof(a));
	    memset(b,0,sizeof(b));
	    memset(man,0,sizeof(man));
	    memset(book,0,sizeof(book));
	    memset(G,0,sizeof(G));
		scanf("%s",s0);
		s3[s0]=1;
		s1[1]=s0;
		for(i=1;i<=n;i++)
		{
			scanf("%s",s0);
			s4[s0]=i;
			s2[i]=s0;
			man[1][i]=i;
		}
		for(i=2;i<=n;i++)
		{
			scanf("%s",s0);
			s3[s0]=i;
			s1[i]=s0;
			for(j=1;j<=n;j++)
			{
				scanf("%s",s0);
				man[i][j]=s4[s0];
			}
		}
		for(i=1;i<=n;i++)
		{
			scanf("%s",s0);
			x=s4[s0];k=n;
			for(j=1;j<=n;j++)
			{
				scanf("%s",s0);
				G[x][s3[s0]]=k--;
			}
		}
		queue<int> p;
		for(i=1;i<=n;i++)
		   p.push(i);  
		while(!p.empty())
	    {
	    	y=p.front();
	    	p.pop();
	    	for(i=1;i<=n;i++)
	    	{
			   z=man[y][i];
			   if(!book[y][z]&&z)
	    	     break;
			}
			book[y][z]=1;
            if(!b[z])
            {
            	b[z]=y;
            	a[y]=z;
			}
			else
			{
			  if(G[z][b[z]]<G[z][y])
			 {
				p.push(b[z]);
				b[z]=y; 
				a[y]=z;	
		      }
		      else
		        p.push(y);
			}
		}
		for(i=1;i<=n;i++)
			 cout<<s1[i]<<' '<<s2[a[i]]<<endl;
		printf("\n");
	}
	return 0;
}错误分析:stl的map了解不清,运用错误,画了好久才找到错误原因。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值