题意:有n个男生和n个女生,每个女生有对所有男生的好感排序,接下来每个男生有对所有女生的好感排序,要求给这些男生女生一一配对,使得每个女生的对象都是她最喜欢的那个。
思路:原型就是稳定婚姻问题,不过原型是每个男生都能取到最满意的妻子,这个可以套用稳定婚姻问题的模板,不过需要把男生女生互换一下,即求每个男生所能找到的最满意的对象。
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn=1e3+5;
int pref[maxn][maxn],order[maxn][maxn],Next[maxn];
int husband[maxn],wife[maxn];
queue<int>q;
void engage(int man,int women)
{
int m=husband[women];
if(m)
{
wife[m]=0; //解除上任婚约
q.push(m); //加入未订婚男士队列
}
wife[man]=women;
husband[women]=man;
}
int main()
{
int n,T,kase=0;
scanf("%d",&T);
while(T--)
{
if(kase++>0)
printf("\n");
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
scanf("%d",&pref[i][j]); //编号为i的男士的j喜欢的人
Next[i]=1; //接下来向排名为1的女士求婚
q.push(i);
wife[i]=0; //没有未婚妻
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
int x;
scanf("%d",&x);
order[i][x]=j; //编号为i的女士心中,编号为x的男士的排名
}
husband[i]=0; //没有未婚夫
}
while(!q.empty())
{
int man=q.front();q.pop();
int women=pref[man][Next[man]++]; //下一个求婚对象
if(!husband[women])
engage(man,women); //女士没有未婚夫,订婚
else if(order[women][man]<order[women][husband[women]])
engage(man,women); //代替现任未婚夫
else
q.push(man); //被拒绝,下次再来求婚
}
for(int i=1;i<=n;i++)
printf("%d\n",wife[i]);
}
}