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