poj3487 The Stable Marriage Problem
经典稳定婚姻问题
“稳定婚姻问题(The Stable Marriage Problem)”大致说的就是100个GG和100个MM按照自己的喜欢程度给所有异性打分排序。每个帅哥都凭自己好恶给每个MM打分:我最爱a,其次爱b,再次爱c...每个帅哥打的分不同,你最爱的可能是我最讨厌的我最爱的可能是他不甚喜欢的。同样,每个美女也同样给每个帅哥打分。现在需要给他们搭配出100对新郎新娘,并且要保证所得到是稳定婚姻的搭配。那么,什么是不稳定的婚姻呢?所谓不稳婚姻是说, 比如说有两对夫妇(M1、F1)和(M2、F2),M1的老婆是F1,但他更爱F2;而F2的老公虽说是M2,但她更爱M1——这样的婚姻就是不稳婚姻,M1和F2理应结合,他们现在各自的婚姻都是错误。
那么,开始激动人心求婚过程啦
第一天上午, 所有的男生都向自己最爱的美眉求婚。下午,每个MM看看自己有没有收到,
收到了多少人的求婚。如果只收到一个男生的求婚,那么就和他订婚。如果收到多于一个GG的求婚,那么就和其中她最爱的那个男人订婚,同时把其他男人都拒掉。如果一个求婚都没有,不要着急,最后总会有的。晚上,检查一遍,如果所有MM都订婚了,OK,万事大吉,明天举行集体婚礼!
但如果还有人没有订婚,那么事情还没有完,第二天还得重复。
第二天上午,所有还没订婚的男生向自己次爱的美眉求婚(因为昨天已经被他们的最爱拒绝了)下午,每个MM再看一遍自己收到订婚的情况。如果她已经订婚了,但是又有一个她更爱的男人来向她求婚,那就把原来那个拒绝掉,再和这个更爱的男人订婚;如果还没订婚,那就和第一天的下午的处理一样。晚上再检查一遍,如果还是有人没有订婚,那第三天再重复。
第三天上午,所有没有订婚的GG,包括第一天订了第二天又被踹出来的(看来要有点忧患意识),再向还没有拒绝过他的MM中他最爱的那个求婚
......
如此周而复始,直到最后大家都订了婚,便一起结婚!哈哈,恭喜恭喜
代码如下,当时WA了好久T_T
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//a对应0号男,z对应25号男
//A对应0号女,Z对应25号女
struct T
{
int love[26];//love[0],love[1],,,,,love[n-1]
int person;//最终订婚的对象
int yao;//已经邀请了0,1,2,,,,yao-1
}man[26];
struct U
{
int love[26];//love[0],love[1],,,,,love[n-1]
int person;//已订婚的对象
int accept[26];//accept[0],,,,accept[num-1]
int num;//有num个男士像她发出邀请
}woman[26];
int n;
int man_num[26];//man_num[0],man_num[1],,,,,man_num[n-1]
int woman_num[26];//woman_num[0],woman_num[1],,,,,woman_num[n-1]
bool check()
{
int i;
for(i=0;i<n;i++)
{
if(man[man_num[i]].person==-1)
{
return false;
}
}
return true;
}
int main()
{
int total;
int i,j;
scanf("%d",&total);
while(total--)
{
scanf("%d",&n);//n个男的n个女的
getchar();
char ch;
for(i=0;i<n;i++)
{
scanf("%c",&ch);
man_num[i]=ch-'a';
getchar();
}
for(i=0;i<n;i++)
{
scanf("%c",&ch);
woman_num[i]=ch-'A';
getchar();
}
char temp[100];
int k;
for(i=0;i<n;i++)
{
k=0;
scanf("%s",temp);
for(j=2;j<n+2;j++)
{
man[man_num[i]].love[k++]=temp[j]-'A';
}
}
for(i=0;i<n;i++)
{
k=0;
scanf("%s",temp);
for(j=2;j<n+2;j++)
{
woman[woman_num[i]].love[k++]=temp[j]-'a';
}
}
//完成输入
for(i=0;i<n;i++)
{
man[man_num[i]].person=-1;
man[man_num[i]].yao=0;
woman[woman_num[i]].person=-1;
}
for(;;)//男士向他喜欢的yao人发出邀请
{
for(j=0;j<n;j++)
{
woman[woman_num[j]].num=0;
}
for(j=0;j<n;j++)//n个男士num[0],num[1],,,,num[n-1]
{
if(man[man_num[j]].person!=-1)//已经订婚就不发出邀请
{
continue;
}
woman[man[man_num[j]].love[man[man_num[j]].yao]].accept[woman[man[man_num[j]].love[man[man_num[j]].yao]].num++]=man_num[j];
man[man_num[j]].yao++;
}
//邀请发出完成一轮
int l;
for(j=0;j<n;j++)//woman_num[j]
{
int max=woman[woman_num[j]].person;
if(max!=-1)
{
for(k=0;k<n;k++)
{
if(woman[woman_num[j]].love[k]==max)
{
max=k;
break;
}
}
}
if(max==-1)
{
max=26;
}
//max是已订婚对象在该女心中的地位,max越大,地位越低
for(k=0;k<woman[woman_num[j]].num;k++)
{
int tem=woman[woman_num[j]].accept[k];
for(l=0;l<n;l++)
{
if(woman[woman_num[j]].love[l]==tem)
{
tem=l;
break;
}
}
if(tem<max)//此时新的对象的地位高于原已订婚对象
{
if(max!=26)
{
man[woman[woman_num[j]].person].person=-1;
}
woman[woman_num[j]].person=woman[woman_num[j]].love[tem];
man[woman[woman_num[j]].person].person=woman_num[j];
max=tem;
}
}
}
if(check())
{
break;
}
}
for(i=0;i<n;i++)//man
{
printf("%c %c\n",man_num[i]+'a',man[man_num[i]].person+'A');
}
printf("\n");
}
return 0;
}