poj 3487 zoj 3120 The Stable Marriage Problem 延迟认可算法(Gale-Shapley算法)

/* 传说中的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; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值