[POJ 3487]The Stable Marriage Problem

本文介绍了一种解决稳定婚姻问题的方法,该问题旨在为两个不同集合的成员寻找最佳配对方案,依据各自的偏好列表。通过使用Gale-Shapley算法找到男性最优的稳定匹配,并提供了一个实现案例。

Description

The stable marriage problem consists of matching members of two different sets according to the member’s preferences for the other set’s members. The input for our problem consists of:

  • 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

The first line gives you the number of tests. The first line of each test case contains integer n (0 < n < 27). Next line describes n male and n female names. Male name is a lowercase letter, female name is an upper-case letter. Then go n lines, that describe preferable lists for males. Next n lines describe preferable lists for females.

Output

For each test case find and print the pairs of the stable marriage, which is male-optimal. The pairs in each test case must be printed in lexicographical order of their male names as shown in sample output. Output an empty line between test cases.

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

题解

$Gale-Shapley$ 模板,可以去 Matrix67的博客 里学。

 1 //It is made by Awson on 2018.1.17
 2 #include <set>
 3 #include <map>
 4 #include <cmath>
 5 #include <ctime>
 6 #include <queue>
 7 #include <stack>
 8 #include <cstdio>
 9 #include <string>
10 #include <vector>
11 #include <cstdlib>
12 #include <cstring>
13 #include <iostream>
14 #include <algorithm>
15 #define LL long long
16 #define Abs(a) ((a) < 0 ? (-(a)) : (a))
17 #define Max(a, b) ((a) > (b) ? (a) : (b))
18 #define Min(a, b) ((a) < (b) ? (a) : (b))
19 #define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))
20 #define writeln(x) (write(x), putchar('\n'))
21 using namespace std;
22 const int N = 30;
23 void read(int &x) {
24     char ch; bool flag = 0;
25     for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
26     for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
27     x *= 1-2*flag;
28 }
29 void write(int x) {
30     if (x > 9) write(x/10);
31     putchar(x%10+48);
32 }
33 
34 int couple, malelike[N+5][N+5], femalelike[N+5][N+5];
35 int malechoice[N+5], femalechoice[N+5];
36 char ch[N+5];
37 queue<int>freemale;
38 
39 void work() {
40     read(couple);
41     for (int i = 0; i < couple; i++) {
42     scanf("%s", ch);
43     freemale.push(ch[0]-'a');
44     }
45     for (int i = 0; i < couple; i++) {
46     scanf("%s", ch);
47     }
48     for (int i = 0; i < couple; i++) {
49     scanf("%s", ch);
50     for (int j = 2; j < 2+couple; j++)
51         malelike[i][j-1] = ch[j]-'A';
52     }
53     for (int i = 0; i < couple; i++) {
54     scanf("%s", ch);
55     for (int j = 2; j < 2+couple; j++)
56         femalelike[i][ch[j]-'a'] = couple-(j-2);
57     femalelike[i][couple] = -1;
58     }
59     for (int i = 0; i < couple; i++) {
60     malechoice[i] = 1, femalechoice[i] = couple;
61     }
62     while (!freemale.empty()) {
63     int male = freemale.front(), female = malelike[male][malechoice[male]];
64     if (femalelike[female][male] > femalelike[female][femalechoice[female]]) {
65         freemale.pop();
66         if (femalechoice[female] != couple) {
67         malechoice[femalechoice[female]]++; freemale.push(femalechoice[female]);
68         }
69         femalechoice[female] = male;
70     }else malechoice[male]++;
71     }
72     for (int i = 0; i < couple; i++) printf("%c %c\n", i+'a', malelike[i][malechoice[i]]+'A');
73 }
74 int main() {
75     int t; read(t);
76     while (t--) {work(); if (t) putchar('\n'); }
77     return 0;
78 }

 

转载于:https://www.cnblogs.com/NaVi-Awson/p/8306147.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值