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

来源:互联网 发布:css网站布局源码 编辑:程序博客网 时间:2024/05/25 18:09
/*传说中的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 26using 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;}

原创粉丝点击