题意:
给你n个男士n个女士,然后给你每个男士中女士的排名,和每个女士中每个男士在他们心中的排名,问你是否可以组成稳定的舞伴,如果存在以下情况(1)男生u和女生v不是舞伴,他们喜欢对方的程度都大于各自当前舞伴的程度,他们就可能抛弃自己现在的舞伴,这样的话匹配就不是稳定的。输出稳定的时候每个男生所匹配的女生。
思路:
哎!本来就是一个最基本的稳定婚姻问题,输入输出的地方被白书翻译出翔了,我C,弄的我怎么敲都过不去,后来看了下白书的代码发现他是先输出男生心目中女生的排名,而他前面说的却不是这个,改了之后还是不过,后来又接着往下看,发现输出的是男生的结果,不是女生,就是一个输入输出整的调了好久,本来我的模板就是我自己写的,还以为是自己的模板写错了。
上面说了那么多废话,下面来说下稳定婚姻问题的思想吧,首先稳定婚姻问题是必然有唯一解的,至于为什么,这个可以去网上找详细证明,如果不想证明,我们可以想一下每个人心中都对所有人排名了,如果剩下一个女生,那么必定会剩下一个男生,所谓剩下的就是他们不能再追求得上自己更喜欢的了,最后就剩他两个了,直接匹配上也是稳定的。对于算法的过程是这样的,我们先把所有男生都扔进队列,队列里的就表示当前没有找到对象的男生,然后男生一个一个的从队列出来,出来后从自己最喜欢的女生开始一个一个访问,如果这个女生当前没有对象,那么直接匹配上,如果有的话就看看是不是自己在那个女生心中的地位比她当前的对象好,如果好,那么直接匹配,那个女生之前的对象将被扔回单身队列,就这样一直到单身队列为空就完事了,算法整体上看感觉男生很可怜,很容易被女生直接扔回去,其实女生更可怜,没有自己的主动权,只能是等着选他的男生中选一个最好的,自己最喜欢的男生可能永远不会去选择他,呵呵,感觉算法比较搞笑....
#include<stdio.h>
#include<string.h>
#include<queue>
#define N 1000 + 10
using namespace std;
int map[N][N] ,sc[N][N];
int mark[N][N];
int nowb[N] ,nowg[N];
void Marry(int n)
{
queue<int>q;
for(int i = 1 ;i <= n ;i++)
q.push(i);
memset(nowb ,255 ,sizeof(nowb));
memset(nowg ,255 ,sizeof(nowg));
memset(mark ,0 ,sizeof(mark));
while(!q.empty())
{
int xin ,tou;
tou = q.front();
q.pop();
for(int i = 1 ;i <= n ;i ++)
{
xin = map[tou][i];
if(mark[tou][xin]) continue;
mark[tou][xin] = 1;
if(nowg[xin] == -1)
{
nowg[xin] = tou;
nowb[tou] = xin;
break;
}
else if(sc[xin][tou] > sc[xin][nowg[xin]])
{
q.push(nowg[xin]);
nowg[xin] = tou;
nowb[tou] = xin;
break;
}
}
}
}
int main ()
{
int t ,n ,i ,j ,a;
scanf("%d" ,&t);
while(t--)
{
scanf("%d" ,&n);
for(i = 1 ;i <= n ;i ++)
for(j = 1 ;j <= n ;j ++)
scanf("%d" ,&map[i][j]);
for(i = 1 ;i <= n ;i ++)
{
for(j = 1 ;j <= n ;j ++)
{
scanf("%d" ,&a);
sc[i][a] = n - j + 1;
}
}
Marry(n);
for(i = 1 ;i <= n ;i ++)
printf("%d
" ,nowb[i]);
if(t) puts("");
}
return 0;
}