poj3487-The Stable Marriage Problem

poj3487-The Stable Marriage Problem

The Stable Marriage Problem
Time Limit: 1000MS

Memory Limit: 65536K
Total Submissions: 3084

Accepted: 1311
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
Source
Southeastern Europe 2007

穩定婚姻問題。
誰告白誰在婚姻中占主導地位。
試想,{男生從最喜歡的女生開始告白,直到有一個女生接受他},比{他等待着女生向自己告白,只能選擇其中自己最喜歡的一個}男生在婚姻中佔優勢。

延遲認可算法 流程:
(1)初始化所有男生被拒絕
(2)當還有男生沒被考慮
———(2.1)每個男生從自己最喜歡的女生開始找一個沒有拒絕自己的女生告白
———(2.2)女生從向自己告白的男生裏選擇一個自己最喜歡的男生,對他延遲考慮(作爲備胎??),並拒絕其他向自己告白的男生(我們這些屌絲)。可以在(2.1)的過程維護(2.2)。

結論:我們是否應該主動一點?

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 200;

int n;
char boyName[MAXN][MAXN], girlName[MAXN][MAXN], s[MAXN];
int power[MAXN][MAXN], boyWant[MAXN][MAXN], girlWant[MAXN][MAXN], nowSheHas[MAXN], boy[MAXN], girl[MAXN];
bool refuse[MAXN][MAXN];


void solve(){
    memset(refuse, 0, sizeof refuse);
    memset(nowSheHas, 0, sizeof nowSheHas);
    int flag1 = 1;
    while (flag1) {
      flag1 = 0;
      for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= n; ++j) {
          int by = boy[i];
          int gl = boyWant[by][j];
          if (nowSheHas[gl] == by) break;
          if (!refuse[by][gl]) {
            if (power[gl][nowSheHas[gl]] > power[gl][by])
              refuse[by][gl] = 1, flag1 = 1;
            else{
              if (nowSheHas[gl]) flag1 = 1;
              refuse[nowSheHas[gl]][gl] = 1;
              nowSheHas[gl] = by;
            }
            break;
          }
        }
    }
    for (int i = 1; i <= n; ++i)
      for (int j = 1; j <= n; ++j)
        if (nowSheHas[girl[j]] == boy[i])
          printf("%c %c\n", boy[i]+'a'-1, girl[j]+'A'-1);
    printf("\n");
}

int main()
{
    int T;
    scanf("%d", &T);
    while (T--) {
      scanf("%d", &n);
      for (int i = 1; i <= n; ++i) {
        scanf("%s", boyName[i]);
        boy[i] = boyName[i][0] - 'a' + 1;
      }
      for (int i = 1; i <= n; ++i) {
        scanf("%s", girlName[i]);
        girl[i] = girlName[i][0] - 'A' + 1;
      }
      for (int i = 1; i <= n; ++i) {
        scanf("%s", s);
        int tot = 0, flag = 0;
        for (int j = 0; j < strlen(s); ++j) {
          if (s[j] == ':' && !flag) flag = 1;
          else if (flag) boyWant[boy[i]][++tot] = s[j] - 'A' + 1;
        }
      }
      for (int i = 1; i <= n; ++i) {
        scanf("%s", s);
        int tot = 0, flag = 0;
        for (int j = 0; j < strlen(s); ++j) {
          if (s[j] == ':' && !flag) flag = 1;
          else if (flag) girlWant[girl[i]][++tot] = s[j] - 'a' + 1;
        }
        for (int j = 1; j <= n; ++j)
          power[girl[i]][girlWant[girl[i]][j]] = n - j + 1;
      }
      solve();
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章