/*
传说中的Gale-Shapley算法。。。
第一次听说这个算法
百度一下才知道此算法已经有其实际应用了。。。
此题从早上八点开始看
先是用了n多队列写
测试倒是通过了
就是提交时老SF
然后就看到了网上说的Gale-Shapley算法
从学习算法然后写代码调试
最后到提交AC时已经是下午4点半
本来以为今天肯定过不了
没先到提交时一次通过
喜悦之情顿生。。。
不说废话了
下面讲一下思路:
该算法的总体思路是
让男生根据他们对女生的喜欢程度对女生进行追求
女生则根据前来追求的对象决定是接受还是拒绝
接受还是拒绝取决于该女生对该男生的喜欢程度
具体实现是用两个矩阵
1. libman[][]记录男生喜欢的女生列表
从喜欢到不喜欢降序排列
2.ladyscore[][]记录女生对各个男生所打的分数
分数越高则表明女生对该男生的心仪程度越高
男生有两种状态
自由男和约会男
我们的目标是让所有的自由男变成约会男
所以用一个栈freeman(队列亦可)装自由男
当栈空时表明约会结束
用数组man[]来记录对应编号的男生下一个约会目标
用数组lady[]来记录对应编号的女生现任男友的编号
为了便于处理
虚构一个不存在的男友,编号最大,分数最低
意即此人为某女生现任男友时只要有人追求
该女生就会毫不留情地抛弃他
*/
#define LOCAL
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm> //sort()包含在这个头文件中 ps:在大多数情况下sort()比qsort()要快
#define N 26
using namespace std;
int main()
{
#ifdef LOCAL
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
#endif
short ncase,couple,libman[N][N],man[N],ladyscore[N][N],lady[N],male,female,i,j,first=1,a[N];
stack<int> freeman;
string list;
char temp;
cin>>ncase;
while(ncase--)
{
if(first) first=0;
else cout<<endl; //打印实例间的空格
while(!freeman.empty()) freeman.pop(); //清空栈
cin>>couple;
//得到数据
for(i=0;i<couple;i++)
{
cin>>temp;
a[i]=temp-'a'; //用a[]记录男生列表
freeman.push(a[i]); //所有男生(一开始都是自由男)入栈
}
sort(a,a+couple);//对所有输入的男生进行排序一边与后面按字典序输出
for(i=0;i<couple;i++) cin>>temp;
//接收女生列表(由于女生和男生是一一对应的所以这里只是将其接收而并不记录)
for(i=0;i<couple;i++)//记录男生的心仪女生
{
cin>>list;
for(j=0;j<couple;j++)
{
libman[i][j]=list[j+2]-'A';
}
}
for(i=0;i<couple;i++)//女生对他们的追求者一一打分
{
cin>>list;
for(j=0;j<couple;j++)
ladyscore[i][list[j+2]-'a']=couple-j;
}
for(i=0;i<couple;i++)
ladyscore[i][couple]=0;//对"不存在"的男生打最低分
memset(man,0,sizeof(man));
for(i=0;i<N;i++) lady[i]=couple;//这里不能用memset()因为couple是变量而不是常数
while(!freeman.empty())//进行匹配
{
male=freeman.top();//用male记录当前追求者
female=libman[male][man[male]];//用female记录male所追求的女生
if(ladyscore[female][male]>ladyscore[female][lady[female]]) //若当前追求者比其现任男友优秀
{
freeman.pop();//该男生约会成功跳出自由男行列
if(lady[female]!=couple)//如果该女生有前男友
{freeman.push(lady[female]);man[lady[female]]++;}
//将其前男友打入自由男行列,该男生刻意追求他的次喜欢女生
lady[female]=male;//追求者成为该女生现任男友
}
else if(ladyscore[female][male]<ladyscore[female][lady[female]]) //若当前追求者没有其现任男友优秀
man[male]++;//该男生可以追求其次喜欢女生
}
for(i=0;i<couple;i++) //输出约会结果
printf("%c %c\n",a[i]+'a',libman[a[i]][man[a[i]]]+'A');
}
return 0;
}
poj 3487 zoj 3120 The Stable Marriage Problem 延迟认可算法(Gale-Shapley算法)
最新推荐文章于 2020-04-22 16:24:09 发布