稳定婚姻问题模板

题目链接

这题写的一把辛酸泪,第一次用getchar()读入,再加上很少用scanf()读入字符,被输入输出缓冲安排的明明白白,最后放弃治疗,用cin,还是死活没有输出,最后才发现是因为for循环多加了一步,白被坑了有一天。

算法分析:首先把每个男士加入队列,让每一个没配对的男士去向女士请求配对,如果女士没有配偶,直接答应,如果有配偶,就将配偶的优先级和当前男士的优先级作比较,如果更喜欢当前的男士,就把配偶踢掉,重新和这个男士配对,被踢掉的男士重新加入队列。

因为题目要求是有利于男士的配对,这样配对可以保证男士的配偶都是能找到的最好的,女士的是能找到最差的。

如果想有利于女士的配对,直接把主动的换成女士就好。

总而言之,就是主动者得利。

具体证明可看这个博文:http://blog.sina.com.cn/s/blog_8897e5420101bdr4.html

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 int a[30],b[30],m_like[30][30],w_like[30][30],now[30],wife[30],husband[30];
 5 queue<int> q;
 6 void engage(int man,int woman){
 7     int tmp=husband[woman];
 8     if(tmp!=-1){
 9         q.push(tmp);
10         wife[tmp]=-1;
11     }
12     husband[woman]=man;
13     wife[man]=woman;
14 }
15 int main()
16 {
17     int t;
18     cin>>t;
19     int T=t;
20     while(t--)
21     {if(T!=t+1) cout<<endl;
22     int n;cin>>n;
23     memset(a,0,sizeof(a));
24     memset(b,0,sizeof(b));
25         char x;
26         for(int i=1;i<=n;i++){
27             cin>>x;
28             a[x-'a']=1;//按字典序输出,最后输出是从小到到遍历,如果有就输出,没有就不输出 
29         }
30         for(int i=1;i<=n;i++){
31             cin>>x;
32             b[x-'A']=1;
33         }
34         for(int i=0;i<n;i++){
35             string s;cin>>s;
36             char ch=s[0],c;//s[0]是男士,s[1]是冒号,女士从s[2]开始 
37             for(int j=2;j<n+2;j++) {
38                 c=s[j];
39                 m_like[ch-'a'][j]=c-'A';            
40             }//将男士加入队列,now数组标记男士配对到第几个女士了,注意j从2开始,所以now数组也从2开始 
41             q.push(ch-'a');now[ch-'a']=2,wife[ch-'a']=-1;
42         }
43         for(int i=0;i<n;i++){
44             string s;cin>>s;
45             char ch=s[0],c;
46             for(int j=2;j<n+2;j++){
47                 c=s[j];
48                 w_like[ch-'A'][c-'a']=j;            
49             }    husband[ch-'A']=-1;
50         }
51         while(!q.empty()){
52             int man=q.front();q.pop();
53             int woman=m_like[man][now[man]++];
54 //如果女士没有配偶,直接答应,如果有配偶,就将配偶的优先级和当前男士的优先级作比较,如果更喜欢当前的男士,重新配对
55             if(husband[woman]==-1||(w_like[woman][husband[woman]]>w_like[woman][man]))    engage(man,woman);
56             else q.push(man);
57         }
58         for(int i=0;i<n;i++){
59             if(a[i]) cout<<char(i+'a')<<" "<<char(wife[i]+'A')<<endl;
60         }
61     }
62 }
原文地址:https://www.cnblogs.com/qingjiuling/p/10404981.html