题意: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;
}