EOJ:The Stable Marriage Problem
The Stable Marriage Problem
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submits: 40 | Accepted: 11 |
Description
- a set M of n males;
- a set F of n females;
- for each male and female we have a list of all the members of the opposite gender in order of preference (from the most preferable to the least).
A marriage is a one-to-one mapping between males and females. A marriage is called stable, if there is no pair (m, f) such that f ∈ F prefers m ∈ M to her current partner and m prefers f over his current partner. The stable marriage A is called male-optimal if there is no other stable marriage B, where any male matches a female he prefers more than the one assigned in A.
Given preferable lists of males and females, you must find the male-optimal stable marriage.
Input
Output
Sample Input
2 3 a b c A B C a:BAC b:BAC c:ACB A:acb B:bac C:cab 3 a b c A B C a:ABC b:ABC c:BCA A:bac B:acb C:abc
Sample Output
a A b B c C a B b A c C
原题地址:http://202.120.106.94/onlinejudge/problemshow.php?pro_id=162
——————————————————————————————————————————————————————————————————
以下为转载:
稳定婚姻问题(The Stable Marriage Problem)
”大致说的就是100个SSGG和100个PPMM按照自己的喜欢程度给所有异性打分排序。每个帅哥都凭自己好恶给每个MM打分:我最爱a,其次爱b,再次爱c...每个帅哥打的分不同,你最爱的可能是我最讨厌的我最爱的可能是他不甚喜欢的。同样,每个美女也同样给每个帅哥打分。现在需要给他们搭配出100对新郎新娘,并且要保证所得到是稳定婚姻的搭配。那么,什么是不稳定的婚姻呢?所谓不稳婚姻是说, 比如说有两对夫妇(M1、F1)和(M2、F2),M1的老婆是F1,但他更爱F2;而F2的老公虽说是M2,但她更爱M1——这样的婚姻就是不稳婚姻,M1和F2理应结合,他们现在各自的婚姻都是错误。
那么,我们如何找到一个算法来构造这100个稳定婚姻呢?这个是数学界切切实实研究过的问题。对于以前没有接触过这个问题的人,这个理论最出人意外的结论是: 传统的求爱、结婚过程是male-optimal(男生主动)的,也就是说,男性能够得到尽可能好的心上人,女性却不然。这个问题和图论有关, 最早是由两个美国数学家1962年在American Mathematical Monthly上提出的,相关的参考文献其实很多,下面这个网页大概是讲得最通俗易懂的: "The Stable Marriage Problem" by Harry Mairson,http://www.cs.columbia.edu/~evs/intro/stable/writeup.html
那么,开始激动人心求婚过程啦
第一天上午, 所有的男生都向自己最爱的美眉求婚。下午,每个MM看看自己有没有收到, 收到了多少人的求婚。如果只收到一个男生的求婚,那么就和他订婚。如果收到多于一个GG的求婚,那么就和其中她最爱的那个男人订婚,同时把其他男人都拒掉。如果一个求婚都没有,不要着急,最后总会有的。晚上,检查一遍,如果所有MM都订婚了,OK,万事大吉,明天举行集体婚礼!
但如果还有人没有订婚,那么事情还没有完,第二天还得重复。
第二天上午,所有还没订婚的男生向自己次爱的美眉求婚(因为昨天已经被他们的最爱拒绝了)下午,每个MM再看一遍自己收到订婚的情况。如果她已经订婚了,但是又有一个她更爱的男人来向她求婚,那就把原来那个拒绝掉,再和这个更爱的男人订婚;如果还没订婚,那就和第一天的下午的处理一样。晚上再检查一遍,如果还是有人没有订婚,那第三天再重复。
第三天上午,所有没有订婚的GG,包括第一天订了第二天又被踹出来的(看来要有点忧患意识),再向还没有拒绝过他的MM中他最爱的那个求婚
......
如此周而复始,直到最后大家都订了婚,便一起结婚!哈哈,恭喜恭喜
这么个过程,数学上可以证明如下性质:
1) 这个过程会中止,也就是说,总有大家都订了婚的一天,不可能无限循环。
2) 中止后所有的婚姻是稳定婚姻。我们能证明的是,通过上面那个求婚过程,所有的婚姻都是稳定的,没有人犯错误。
3) 比较引人注目的是,这个过程是male-optimal(男生主动)的,男性能够获得尽可能好的伴侣,比如说最后有二十个女人拒绝了他,他仍然能够得到剩下的八十个女人中他最爱的那一个。
4) 更有甚者,这个过程是female-pessimal的,女人总是在可能的情况下被最不喜欢的人追上。这一点没有那么直观的理解,勉强要解释的话,可以这么看:虽说女人每换一次订婚对象,都往上升一层,但起点可能很低,虽说在一步步接近她最爱的目标,但最后往往达不到。比如说还差三十名就达到她最爱的人了,但这时Game Over,所有的人都已订了婚,这样她也只能死了心了!还有三十个她更爱的人还没向她求过婚,可是她也无可奈何了...
对于MALE-OPTIMAL的算法如下
function stableMatching {
Initialize all m ∈ M and w ∈ W to free
while ∃ free man m who still has a woman w to propose to
{
w = m's highest ranked such woman who he has not proposed to yet
if w is free (m, w)
become engaged
else some pair (m', w) already exists
if w prefers m to m'
(m, w) become engaged
m' becomes free
else (m', w) remain engaged
}
}
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<memory.h>
4 #include<string.h>
5 #include<queue>
6 using namespace std;
7 char mname[30],fname[30],str[100];
8 int floc[30],mloc[30],mmatch[30],fmatch[30],fprefer[30][30],mprefer[30][30];
9 int i,j,k,t,n,female,male;
10 int cmp(const void *a,const void *b)
11 {
12 return(*(char *)a-*(char *)b);
13 }
14 int main()
15 {
16 scanf("%d",&t);
17 while (t--)
18 {
19 queue<int> q;
20 memset(floc,0,sizeof(floc));
21 memset(mloc,0,sizeof(mloc));
22 scanf("%d",&n);
23 getchar();
24 gets(str);
25 qsort(str,strlen(str),sizeof(str[0]),cmp);
26 for (j=3*n-1;j<=4*n-2;j++)
27 {
28 mname[j-3*n+2]=str[j]-97;
29 mloc[str[j]-97]=j-3*n+2;
30 }
31 for (j=2*n-1;j<=3*n-2;j++)
32 {
33 fname[j-2*n+2]=str[j]-65;
34 floc[str[j]-65]=j-2*n+2;
35 }
36 for (j=1;j<=2*n;j++)
37 {
38 gets(str);
39 if (str[0]>='A'&&str[0]<='Z')
40 {
41 fprefer[floc[str[0]-65]][0]=0;
42 for (k=2;k<=n+1;k++)
43 fprefer[floc[str[0]-65]][k-1]=str[k]-97;
44 }
45 else
46 {
47 mprefer[floc[str[0]-97]][0]=0;
48 for (k=2;k<=n+1;k++)
49 mprefer[mloc[str[0]-97]][k-1]=str[k]-65;
50 }
51 }
52 for (i=1;i<=n;i++)
53 {
54 q.push(i);
55 fmatch[i]=-1;
56 }
57 while (!q.empty())
58 {
59 male=q.front();
60 q.pop();
61 female=floc[mprefer[male][++mprefer[male][0]]];
62 if (fmatch[female]==-1)
63 {
64 fmatch[female]=male;
65 mmatch[male]=female;
66 }
67 else
68 for (i=1;i<=n;i++)
69 if (fprefer[female][i]==mname[male]||fprefer[female][i]==mname[fmatch[female]])
70 {
71 if (fprefer[female][i]==mname[male])
72 {
73 q.push(fmatch[female]);
74 fmatch[female]=male;
75 mmatch[male]=female;
76 }
77 break;
78 }
79 if (fmatch[female]!=male)
80 q.push(male);
81 }
82 for (i=1;i<=n;i++)
83 printf("%c %c\n",mname[i]+97,fname[mmatch[i]]+65);
84 if (t!=0) printf("\n");
85 }
86 return 0;
87 }