POJ 3487 The Stable Marriage Problem (稳定婚姻问题)

题意:http://poj.org/problem?id=3487


/*男生向女生求爱,男生最优稳定匹配*/
#include<cstdlib>
#include<algorithm>
#include<iostream>
using namespace std;


#define MAXN 50
int Mpref[MAXN][MAXN]; // Mpref[i][j]表示男生i第j偏爱的女生
int Wpref[MAXN][MAXN]; // Wpref[i][j]表示女生i对男生j的偏爱值
int ptr[MAXN]; // 指向男生下一个求爱的对象
int mailBox[MAXN][MAXN], cnt[MAXN]; // 女生的收件箱
int Mmatch[MAXN]; //男生的配偶
int Wmatch[MAXN]; //女生的配偶
int que[MAXN], front, rear; //队列中储存没有找到对象的男生


void Gale_Shapley ( int n )
{
	memset(Mmatch,-1,sizeof(Mmatch)); //开始时所有男生的配偶都为-1
	memset(Wmatch,-1,sizeof(Wmatch)); //开始时所有女生的配偶都为-1
	memset(ptr,0,sizeof(ptr)); // 开始时所有男生求爱的对象都是他最偏爱的女生
	front = rear = 0;


	int boy, girl, i, j;
	for ( i = 0; i < n; i++ ) que[rear++] = i;


	while ( front != rear )
	{
		memset(cnt,0,sizeof(cnt));
		while ( front != rear )
		{
			boy = que[front++];
			girl = Mpref[boy][ptr[boy]];
			mailBox[girl][cnt[girl]++] = boy;
		}


		front = rear = 0;
		for ( i = 0; i < n; i++ )
		{
			for ( j = 0; j < cnt[i]; j++ )
			{
				boy = mailBox[i][j];
				if ( Wmatch[i] == -1 || Wpref[i][boy] < Wpref[i][Wmatch[i]] )
				{
					if ( Wmatch[i] != -1 ) // 若女生已经订婚,则原配被挤掉
					{
						Mmatch[Wmatch[i]] = -1; // 原配的配偶边为-1
						ptr[Wmatch[i]]++;  // 修改原配的下一个求爱对象
						que[rear++] = Wmatch[i]; // 将原配放进队列
					}
					Wmatch[i] = boy; 
					Mmatch[boy] = i;
				}
				else
				{
					que[rear++] = boy;
					ptr[boy]++;
				}
			}
		}
	}
}
		
int main()
{
	int cs, n;
	char ch[MAXN], man[MAXN], woman[MAXN];;
	int hash[MAXN*3];
	cin >> cs;
	while ( cs-- )
	{
		cin >> n;
		int i, j;
		for ( i = 0; i < n; i++ )
		{
			cin >> ch;
			hash[ch[0]] = i;
			man[i] = ch[0];
		}


		for ( i = 0; i < n; i++ )
		{
			cin >> ch;
			hash[ch[0]] = i;
			woman[i] = ch[0];
		}


		for ( i = 0; i < n; i++ )
		{
			cin >> ch;
			for ( j = 0; j < n; j++ )
				Mpref[ hash[ch[0]] ][j] = hash[ch[j+2]];
		}


		for ( i = 0; i < n; i++ )
		{
			cin >> ch;
			for ( j = 0; j < n; j++ )
				Wpref[ hash[ch[0]] ][ hash[ch[j+2]] ] = j;
		}


		Gale_Shapley ( n );
		sort(man,man+n);
		for ( i = 0; i < n; i++ )
			cout << man[i] << ' ' << woman[ Mmatch[ hash[man[i]] ] ] << endl;
		if ( cs ) cout << endl;
	}
	return 0;
}
		



/*男生向女生求爱,男生最优稳定匹配*/
#include<cstdlib>
#include<algorithm>
#include<iostream>
using namespace std;

#define N 1001
struct People
{
    int opp, aim; //opp表示结婚对象,opp==-1表示还没结婚;aim指向男生的下一个求爱对象
    int list[N]; //man使用,man[i].list[j]表示男生i“第j”偏爱的女生
    int priority[N]; //woman使用,woman[i].priority[j]表示女生i对男生j的偏爱的名次
    void Init() { opp = -1; aim = 0; }
} man[N], woman[N];

struct Request
{
    int opp, own;
} request[N];

int que[N], front, rear;

void Gale_Shapley ( int n )
{
	int cnt, m, w, i;
	for ( i = rear = 0; i < n; i++ ) que[rear++] = i;

    while ( front != rear )
    {
        cnt = 0;
		while ( front != rear )
		{
			m = que[front++];
			request[cnt].opp = man[m].list[man[m].aim];
            request[cnt].own = m;
            man[m].aim++; cnt++;
		}

        if ( cnt == 0 ) break;
		front = rear = 0;
        for ( i = 0; i < cnt; i++ )
        {
            m = request[i].own;
            w = request[i].opp;
            if ( woman[w].opp == -1 || woman[w].priority[m] < woman[w].priority[woman[w].opp] )
            {
                if ( woman[w].opp != -1 )
				{
                    man[woman[w].opp].opp = -1;
					que[rear++] = woman[w].opp;
				}
                woman[w].opp = m;
                man[m].opp = w;
            }
			else que[rear++] = m;
        }
    }
}

int main()
{
    int cs, n;
    char ch[N], mch[N], wch[N];;
    int hash[N*3];
    cin >> cs;
    while ( cs-- )
    {
        cin >> n;
        int i, j;
        for ( i = 0; i < n; i++ )
        {
            cin >> ch;
            hash[ch[0]] = i;
            mch[i] = ch[0];
			man[i].Init ();
        }


        for ( i = 0; i < n; i++ )
        {
            cin >> ch;
            hash[ch[0]] = i;
            wch[i] = ch[0];
			woman[i].Init ();
        }


        for ( i = 0; i < n; i++ )
        {
            cin >> ch;
            for ( j = 0; j < n; j++ )
                man[ hash[ch[0]] ].list[j] = hash[ch[j+2]];
        }


        for ( i = 0; i < n; i++ )
        {
            cin >> ch;
            for ( j = 0; j < n; j++ )
                woman[ hash[ch[0]] ].priority[ hash[ch[j+2]] ] = j;
        }


        Gale_Shapley ( n );
        sort(mch,mch+n);
        for ( i = 0; i < n; i++ )
            cout << mch[i] << ' ' << wch[ man[ hash[mch[i]] ].opp ] << endl;
        if ( cs ) cout << endl;
    }
    return 0;
}



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值