貌似又叫延迟认可算法?
问题模型及解答方法可以参考:
大学招生问题模型也可以参考这个。
Poj 3487 The Stable Marriage Problem
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int N=30;
int n,data[N];
int gg[N][N]; //gg[i][j]=k i男第j喜欢k女
int mm[N][N]; //mm[i][j]=k j男是i女第k喜欢的
int glike[N]; //glike[i]=j i男目前最喜欢j女
int mlike[N]; //mlike[i]=j i女目前更喜欢j男
queue<int> q;
void Stable_marriage ()
{
memset(glike,0,sizeof(glike)); //男生最喜欢的全部初始为0
memset(mlike,-1,sizeof(mlike)); //所有女生都未被表白
while (!q.empty())
{
int pm = q.front ();
q.pop ();
int pf = gg[pm][glike[pm]]; //pm男向当前喜欢的女生表白
glike[pm]++;
if (mlike[pf] < 0) //还没有人向她表白
mlike[pf] = pm;
else if (mm[pf][mlike[pf]] < mm[pf][pm]) //对以前向她表白的人的喜欢程度高于现在的(数值小)
q.push (pm); //该男重新入队
else
{//否则将原来男入队,并重新分配
q.push (mlike[pf]);
mlike[pf] = pm;
}
}
int i;
for (i=0;i<26;i++)
if (mlike[i]>-1)
glike[mlike[i]] = i;
for (i=0;i<n;i++)
printf("%c %c\n",data[i]+'a',glike[data[i]]+'A');
printf("\n");
}
int main ()
{
int T,i,j;
scanf("%d",&T);
while (T--)
{
scanf("%d",&n);
char str[30];
while (!q.empty())
q.pop();
for (i=0;i<n;i++)
{
scanf("%s",str);
data[i]=str[0]-'a';
q.push(data[i]);
}
sort(data,data+n);
for (i=0;i<n;i++)
scanf("%*s");
for (i=0;i<n;i++)
{
scanf("%s",str);
for (j=0;j<n;j++)
gg[str[0]-'a'][j]=str[j+2]-'A';
}
for (i=0;i<n;i++)
{
scanf("%s",str);
for (j=0;j<n;j++)
mm[str[0]-'A'][str[j+2]-'a']=j;
}
Stable_marriage();
}
return 0;
}
Hdu 1522 Marriage is Stable
//#pragma comment(linker, "/STACK:102400000,102400000")
#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#include <map>
#include <string>
#include <algorithm>
using namespace std;
const int N=505;
int n,data[N];
int gg[N][N]; //gg[i][j]=k i男第j喜欢k女
int mm[N][N]; //mm[i][j]=k j男是i女第k喜欢的
int glike[N]; //glike[i]=j i男目前最喜欢j女
int mlike[N]; //mlike[i]=j i女目前更喜欢j男
queue<int> q;
void Stable_marriage ()
{
memset(glike,0,sizeof(glike)); //男生最喜欢的全部初始为0
memset(mlike,-1,sizeof(mlike)); //所有女生都未被表白
while (!q.empty())
{
int pm = q.front ();
q.pop ();
int pf = gg[pm][glike[pm]]; //pm男向当前喜欢的女生表白
glike[pm]++;
if (mlike[pf] < 0) //还没有人向她表白
mlike[pf] = pm;
else if (mm[pf][mlike[pf]] < mm[pf][pm]) //对以前向她表白的人的喜欢程度高于现在的(数值小)
q.push (pm); //该男重新入队
else
{//否则将原来男入队,并重新分配
q.push (mlike[pf]);
mlike[pf] = pm;
}
}
for (int i=0;i<n;i++)
if (mlike[i]>-1)
glike[mlike[i]] = i;
}
int main ()
{
while (~scanf("%d",&n))
{
char str[205];
while (!q.empty())
q.pop();
map<string,int> gnum,mnum;
string gname[N],mname[N];
int i,j,gid=0,mid=0; //男生编号,女生编号
for (i=0;i<n;i++)
{
scanf("%s",str);
gnum[str]=gid;
gname[gid]=str;
q.push(gid);
for (j=0;j<n;j++)
{
scanf("%s",str);
if (mnum.find(str)==mnum.end())
{
mname[mid]=str;
mnum[str]=mid++;
}
gg[gid][j]=mnum[str];
}
gid++;
}
for (i=0;i<n;i++)
{
scanf("%s",str);
int tmp=mnum[str];
for (j=0;j<n;j++)
{
scanf("%s",str);
mm[tmp][gnum[str]]=j;
}
}
Stable_marriage();
for (i=0;i<n;i++)
cout<<gname[i]<<' '<<mname[ glike[i] ]<<endl;
printf("\n");
}
return 0;
}