zoukankan      html  css  js  c++  java
  • 【HDU1914 The Stable Marriage Problem】稳定婚姻问题

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

    题目大意:问题大概是这样:有一个社团里有n个女生和n个男生,每位女生按照她的偏爱程度将男生排序,同时每位男生也按照自己的偏爱程度将女生排序。然后将这n个女生和n个男生配成完备婚姻。

    如果存在两位女生A和B,两位男生a和b,使得A和a结婚,B和b结婚,但是A更偏爱b而不是a,b更偏爱A而不是B,则这个婚姻就是不稳定的,A和b可能背着别人相伴而走,因为他俩都认为,与当前配偶比起来他们更偏爱各自的新伴侣。

    如果完备婚姻不是不稳定的,则称其是稳定的。通过证明,可以得到每一个n女n男的社团,都存在稳定婚姻的结论。但是这种情况只在异性的社团中存在。也就是说在同性的社团里面,稳定婚姻的存在性将不再被保证。

    思路:先把所有男士加入队列当中,对于第一个出队列的男士从他喜爱度最高的女士开始求婚,如果找到一个女士还没有结婚,则和她匹配,如果找到一个女士,该女士对他的满意度高于这个女士的未婚夫,则该女士抛弃未婚夫和他进行匹配,她的未婚夫则进队列。已经匹配过的要进行标记,下次不能再匹配了。

    因为每个男士最多和一个女士匹配一次。时间复杂度接近于O(n^2)。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include <queue>
     6 #include <map>
     7 using namespace std;
     8 
     9 const int maxn=50;
    10 int g[maxn][maxn], b[maxn][maxn], visit[maxn][maxn];
    11 int bf[maxn], gf[maxn];
    12 char ch[maxn], str[maxn];
    13 map<char,int>G,M;
    14 map<int,char>GG,MM;
    15 queue<int>q;
    16 int n, T;
    17 
    18 void init()
    19 {
    20     G.clear(), M.clear(), GG.clear(), MM.clear();
    21     memset(visit,0,sizeof(visit));
    22     memset(bf,0,sizeof(bf));
    23     while(!q.empty()) q.pop();
    24 }
    25 
    26 void find(int x)
    27 {
    28     for(int i=n; i>=1; i--)
    29     {
    30         if(visit[x][i]) continue;
    31         visit[x][i]=1;
    32         int y=b[x][i];
    33         if(!bf[y])
    34         {
    35             bf[y]=x;
    36             gf[x]=y;
    37             return ;
    38         }
    39         else
    40         {
    41             if(g[y][x]>g[y][ bf[y] ])
    42             {
    43                 q.push(bf[y]);
    44                 bf[y]=x;
    45                 gf[x]=y;
    46                 return ;
    47             }
    48         }
    49     }
    50 }
    51 
    52 void Solve()
    53 {
    54     for(int i=1; i<=n; i++) q.push(i);
    55     while(!q.empty())
    56     {
    57         int x=q.front();
    58         q.pop();
    59         find(x);
    60     }
    61     sort(ch+1,ch+n+1);
    62     for(int i=1; i<=n; i++)
    63         printf("%c %c
    ",ch[i],MM[ gf[ G[ch[i]] ] ]);
    64 }
    65 
    66 int main()
    67 {
    68     cin >> T;
    69     while(T--)
    70     {
    71         cin >> n;
    72         init();
    73         for(int i=1; i<=n; i++) cin >> ch[i], G[ ch[i] ]=i, GG[i]=ch[i];
    74         for(int i=1; i<=n; i++) cin >> ch[n+i],  M[ ch[n+i] ]=i, MM[i]=ch[n+i];
    75         for(int i=1; i<=n; i++)
    76         {
    77             scanf("%s",str+1);
    78             int x=G[ str[1] ];
    79             for(int j=3; j<=n+2; j++)
    80             {
    81                 int y=M[ str[j] ];
    82                 b[x][n-j+3]=y;
    83             }
    84         }
    85         for(int i=1; i<=n; i++)
    86         {
    87             scanf("%s",str+1);
    88             int x=M[ str[1] ];
    89             for(int j=3; j<=n+2; j++)
    90             {
    91                 int y=G[ str[j] ];
    92                 g[x][y]=n-j+3;
    93             }
    94         }
    95         Solve();
    96         if(T)puts("");
    97     }
    98 }
    View Code
  • 相关阅读:
    LeetCode Count of Range Sum
    LeetCode 158. Read N Characters Given Read4 II
    LeetCode 157. Read N Characters Given Read4
    LeetCode 317. Shortest Distance from All Buildings
    LeetCode Smallest Rectangle Enclosing Black Pixels
    LeetCode 315. Count of Smaller Numbers After Self
    LeetCode 332. Reconstruct Itinerary
    LeetCode 310. Minimum Height Trees
    LeetCode 163. Missing Ranges
    LeetCode Verify Preorder Serialization of a Binary Tree
  • 原文地址:https://www.cnblogs.com/kane0526/p/3258356.html
Copyright © 2011-2022 走看看