• HDU 1522 -- Marriage is Stable (模板题&总结稳定婚姻算法)


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1522

    Marriage is Stable

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 1299    Accepted Submission(s): 690
    Special Judge


    Problem Description
    Albert, Brad, Chuck are happy bachelors who are in love with Laura, Marcy, Nancy. They all have three choices. But in fact, they do have some preference in mind. Say Albert, he likes Laura best, but that doesn't necesarily mean Laura likes him. Laura likes Chuck more than Albert. So if Albert can't marry Laura, he thinks Nancy a sensible choice. For Albert, he orders the girls Laura > Nancy > Marcy.

    For the boys:

    Albert: Laura > Nancy > Marcy
    Brad: Marcy > Nancy > Laura
    Chuck: Laura > Marcy > Nancy

    For the girls:

    Laura: Chuck > Albert > Brad
    Marcy: Albert > Chuck > Brad
    Nancy: Brad > Albert > Chuck

    But if they were matched randomly, such as

    Albert <-> Laura 
    Brad <-> Marcy
    Chuck <-> Nancy

    they would soon discover it's not a nice solution. For Laura, she likes Chuck instead of Albert. And what's more, Chuck likes Laura better than Nancy. So Laura and Chuck are likely to come together, leaving poor Albert and Nancy.

    Now it's your turn to find a stable marriage. A stable marriage means for any boy G and girl M, with their choice m[G] and m[M], it will not happen that rank(G, M) < rank(G, m[G])and rank(M, G) < rank(M, m[M]).
     
     
    Input
    Each case starts with an integer n (1 <= n <= 500), the number of matches to make.

    The following n lines contain n + 1 names each, the first being name of the boy, and rest being the rank of the girls.

    The following n lines are the same information for the girls.

    Process to the end of file.
     
     
    Output
    If there is a stable marriage, print n lines with two names on each line. You can choose any one if there are multiple solution. Print "Impossible" otherwise.

    Print a blank line after each test.
     
     
    Sample Input
    3
    Albert Laura Nancy Marcy
    Brad Marcy Nancy Laura
    Chuck Laura Marcy Nancy
    Laura Chuck Albert Brad
    Marcy Albert Chuck Brad
    Nancy Brad Albert Chuck
     
     
    Sample Output
    Albert Nancy
    Brad Marcy
    Chuck Laura
     
     
    稳定婚姻算法(G-S算法)介绍:

    一、问题引入

    有n个男生n个女生,每个男生依照喜欢程度对n个女生进行了排序,同理每个女生也依照喜欢程度对n个男生进行了排序,现要将他们一一配对,要求所有的配对是稳定的,即不会出现一个女生相对自己配对的男生更喜欢另一个男生,而这个男生也更喜欢她的情况。

    二、算法步骤描述:

      第一轮,每个男人都选择自己名单上排在首位的女人,并向她表白。这种时候会出现两种情况:

    (1)该女士还没有被男生追求过,则该女士接受该男生的请求。

    (2)若该女生已经接受过其他男生的追求,那么该女生会将该男士与她的现任男友进行比较,若更喜欢她的男友,那么拒绝这个人的追求,否则,抛弃其男友……

      第一轮结束后,有些男人已经有女朋友了,有些男人仍然是单身。

           在第二轮追女行动中,每个单身男都从所有还没拒绝过他的女孩中选出自己最中意的那一个,并向她表白,不管她现在是否是单身。这种时候还是会遇到上面所说的两种情况,还是同样的解决方案。直到所有人都不再是单身。

     三、算法总结:

    (1)无论男子的迭代排序如何,G-S算法每次返回的匹配S都是唯一的;

    (2)匹配S中所有求爱方的伴侣是他们各自的最佳有效伴侣(the best valid partner);

    (3)匹配S中所有被求爱方的伴侣是他们各自的最差有效伴侣(the wrost valid partner);

    (4)也就是说,对于任意可以进行稳定匹配的二分图,对于任意点集,其最佳(差)有效伴侣是互不相同的。

    题意:有n个男生和n个女生,每行给出每个人的名字,后面跟着对n个异性的好感度排名,要求输出男女两两结合的稳定婚姻匹配。

    解析:此题关键在于将字符串之间的关系转换成编号关系,然后套用稳定婚姻算法即可,下面为AC代码(可作为稳定匹配算法模板)。

     1 #include <iostream>
     2 #include <cstring>
     3 #include <map>
     4 #include <string>
     5 #define MAXN 510
     6 using namespace std;
     7 int mm[MAXN][MAXN], gg[MAXN][MAXN], p[MAXN];  // p[i]表示第i个boy已表白人数
     8 // mm[i][j]表示第i个girl对编号为j的boy的好感排位,gg[i][j]表示第i个boy第j喜欢的girl编号,注意意义不同
     9 int gg_match[MAXN], mm_match[MAXN];  // gg_match[i]表示第i个boy已匹配的girl编号
    10 string ss[MAXN*2], str;   // ss[i]表示编号为i的name
    11 map<string, int> mp_mm, mp_gg;  // name映射编号
    12 
    13 int main() {
    14     int n;
    15     while (cin >> n) {
    16         mp_gg.clear(); mp_mm.clear();
    17         int cnt = 0;  // 按照girl出现次序给予编号
    18         for (int i = 1; i <= n; i++) {
    19             cin >> ss[i];
    20             mp_gg[ss[i]] = i;
    21             for (int j = 1; j <= n; j++) {
    22                 cin >> str;
    23                 if (mp_mm[str] == 0) {
    24                     mp_mm[str] = ++cnt;
    25                     ss[n+cnt] = str;
    26                 }
    27                 gg[i][j] = mp_mm[str];
    28             }
    29         }
    30         for (int i = 1; i <= n; i++) {
    31             cin >> str;
    32             int a = mp_mm[str];
    33             for (int j = 1; j <= n; j++) {
    34                 cin >> str;
    35                 int b = mp_gg[str];
    36                 mm[a][b] = j;
    37             }
    38         }
    39         bool flag = true;  // 此处开始为算法核心代码,前面只是将字符串关系处理为编号关系
    40         for (int i = 1; i <= n; i++) p[i] = 1;
    41         memset(mm_match, -1, sizeof(mm_match));
    42         memset(gg_match, -1, sizeof(gg_match));
    43         while (flag) {
    44             flag = false;
    45             for (int i = 1; i <= n; i++) {
    46                 if (gg_match[i] == -1 && p[i] <= n) {
    47                     int a = gg[i][p[i]++];
    48                     if (mm_match[a] == -1) mm_match[a] = i, gg_match[i] = a;
    49                     else if (mm[a][i] < mm[a][mm_match[a]]) {
    50                         gg_match[i] = a;
    51                         gg_match[mm_match[a]] = -1;
    52                         mm_match[a] = i;
    53                     }
    54                     flag = true;
    55                 }
    56             }  // end for
    57         } // end while
    58         for (int i = 1; i <= n; i++) cout << ss[i] << ' ' << ss[gg_match[i]+n] << endl;
    59     }
    60     return 0;
    61 }
    View Code

    顺便贴上另外两道稳定匹配题目的AC代码:

    poj 3487 -- The Stable Marriage Problem

     1 #include <iostream>
     2 #include <cstring>
     3 #include <map>
     4 #define MAXN 30
     5 using namespace std;
     6 int mm[MAXN][MAXN], gg[MAXN][MAXN], p[MAXN];
     7 int gg_match[MAXN], mm_match[MAXN];
     8 char idx[2*MAXN];
     9 map<char, int> mp;
    10 int main() {
    11     int t, n;
    12     cin >> t;
    13     while (t--) {
    14         cin >> n;
    15         char ch;
    16         int cnt = 0;
    17         mp.clear();
    18         for (int i = 0; i < 2 * n; i++) cin >> ch;
    19         for (int i = 1; i <= n; i++) {
    20             cin >> idx[i] >> ch;
    21             mp[idx[i]] = i;
    22             for (int j = 1; j <= n; j++) {
    23                 cin >> ch;
    24                 if (mp[ch] == 0) {
    25                     mp[ch] = ++cnt;
    26                     idx[cnt+n] = ch;
    27                 }
    28                 gg[i][j] = mp[ch];
    29             }
    30         }
    31         for (int i = 1; i <= n; i++) {
    32             char gir;
    33             cin >> gir >> ch;
    34             int a = mp[gir];
    35             for (int j = 1; j <= n; j++) {
    36                 cin >> ch;
    37                 int b = mp[ch];
    38                 mm[a][b] = j;
    39             }
    40         }
    41         bool flag = true;
    42         for (int i = 1; i <= n; i++) p[i] = 1;
    43         memset(mm_match, -1, sizeof(mm_match));
    44         memset(gg_match, -1, sizeof(gg_match));
    45         while (flag) {
    46             flag = false;
    47             for (int i = 1; i <= n; i++) {
    48                 if (gg_match[i] == -1 && p[i] <= n) {
    49                     int a = gg[i][p[i]++];
    50                     if (mm_match[a] == -1) mm_match[a] = i, gg_match[i] = a;
    51                     else if (mm[a][i] < mm[a][mm_match[a]]) {
    52                         gg_match[i] = a;
    53                         gg_match[mm_match[a]] = -1;
    54                         mm_match[a] = i;
    55                     }
    56                     flag = true;
    57                 }
    58             }
    59         }
    60         for (int i = 0; i < 26; i++) {
    61             for (int j = 1; j <= n; j++) if (idx[j] == 'a' + i) {
    62                 cout << idx[j] << ' ' << idx[gg_match[j]+n] << endl;
    63                 break;
    64             }
    65         }
    66         if (t) cout << endl;
    67     }
    68     return 0;
    69 }
    View Code

    hdu 1435 -- Stable Match

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <cstring>
     4 #include <cmath>
     5 #define MAXN 210
     6 using namespace std;
     7 int gg[MAXN][MAXN], mm[MAXN][MAXN];
     8 int gg_match[MAXN], mm_match[MAXN], p[MAXN];
     9 struct node{
    10     double len;
    11     int cap, idx;
    12 } aim[MAXN];
    13 struct input{
    14     int idx, cap;
    15     double x, y, z;
    16 } lau[MAXN], acc[MAXN];
    17 bool cmp(const node &a, const node &b) {
    18     if (fabs(a.len - b.len) < 0.000001) return a.cap > b.cap;
    19     else return a.len < b.len;
    20 }
    21 
    22 int main() {
    23     int t;
    24     cin >> t;
    25     while (t--) {
    26         int n; cin >> n;
    27         for (int i = 1; i <= n; i++) cin >> lau[i].idx >> lau[i].cap >> lau[i].x >> lau[i].y >> lau[i].z;
    28         for (int i = 1; i <= n; i++) cin >> acc[i].idx >> acc[i].cap >> acc[i].x >> acc[i].y >> acc[i].z;
    29         for (int i = 1; i <= n; i++) {
    30             for (int j = 1; j <= n; j++) {
    31                 aim[j].len = sqrt((lau[i].x-acc[j].x)*(lau[i].x-acc[j].x) + (lau[i].y-acc[j].y)*(lau[i].y-acc[j].y) + (lau[i].z-acc[j].z)*(lau[i].z-acc[j].z));
    32                 aim[j].cap = acc[j].cap; aim[j].idx = acc[j].idx;
    33             }
    34             sort(aim+1, aim+n+1, cmp);
    35             for (int j = 1; j <= n; j++) gg[lau[i].idx][j] = aim[j].idx;
    36         }
    37         for (int i = 1; i <= n; i++) {
    38             for (int j = 1; j <= n; j++) {
    39                 aim[j].len = sqrt((acc[i].x-lau[j].x)*(acc[i].x-lau[j].x) + (acc[i].y-lau[j].y)*(acc[i].y-lau[j].y) + (acc[i].z-lau[j].z)*(acc[i].z-lau[j].z));
    40                 aim[j].cap = lau[j].cap; aim[j].idx = lau[j].idx;
    41             }
    42             sort(aim+1, aim+n+1, cmp);
    43             for (int j = 1; j <= n; j++) mm[acc[i].idx][aim[j].idx] = j;
    44         }
    45         bool flag = true;
    46         for (int i = 1; i <= n; i++) p[i] = 1;
    47         memset(mm_match, -1, sizeof(mm_match));
    48         memset(gg_match, -1, sizeof(gg_match));
    49         while (flag) {
    50             flag = false;
    51             for (int i = 1; i <= n; i++) {
    52                 if (gg_match[i] == -1 && p[i] <= n) {
    53                     int a = gg[i][p[i]++];
    54                     if (mm_match[a] == -1) mm_match[a] = i, gg_match[i] = a;
    55                     else if (mm[a][i] < mm[a][mm_match[a]]) {
    56                         gg_match[i] = a;
    57                         gg_match[mm_match[a]] = -1;
    58                         mm_match[a] = i;
    59                     }
    60                     flag = true;
    61                 }
    62             }
    63         }
    64         for (int i = 1; i <= n; i++) cout << i << ' ' << gg_match[i] << endl;
    65         cout << endl;
    66     }
    67     return 0;
    68 }
    View Code
    作者:_kangkang
    本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
  • 相关阅读:
    docker 001 简介
    Golang 学习笔记 003 标识符、变量和常量
    Golang 学习笔记 002 第一个 go 程序
    Golang 学习笔记 001 环境部署
    nginx配置url中带问号的rewrite跳转
    北京市图书馆免费入口
    编译安装Python3
    Python—进程、线程、协程
    Python—I/O多路复用
    Python—Socket
  • 原文地址:https://www.cnblogs.com/kangkang-/p/8412592.html
Copyright © 2020-2023  润新知