HDOJ1914解题报告【稳定婚姻模板】

题目地址:

  http://acm.hdu.edu.cn/showproblem.php?pid=1914

题目概述:

  给出n个男性和n个女性以及他们对其他人做自己伴侣的期望,求匹配方案使尽可能多的人满意。

大致思路:

  题意可能没怎么讲清吧,不过这题是稳定婚姻算法的模板题。

代码:

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstdlib>
  4 #include <cmath>
  5 #include <vector>
  6 #include <ctime>
  7 #include <map>
  8 #include <stack>
  9 #include <set>
 10 #include <queue>
 11 #include <cstring>
 12 #include <algorithm>
 13 using namespace std;
 14 
 15 #define sacnf scanf
 16 #define scnaf scanf
 17 #define maxn 55
 18 #define maxm 26
 19 #define inf 1061109567
 20 #define Eps 0.000001
 21 const double PI=acos(-1.0);
 22 #define mod 1000000007
 23 #define MAXNUM 10000
 24 void Swap(int &a,int &b) {int t=a;a=b;b=t;}
 25 int Abs(int x) {return (x<0)?-x:x;}
 26 typedef long long ll;
 27 
 28 map<char,int> man,woman;
 29 map<int,char> turn;
 30 char temp[maxn];
 31 
 32 int a[maxn][maxn],b[maxn][maxn],n; //a-->男生的期望   b-->女生的期望
 33 int ans[maxn];   //每位男生选中的女生
 34 int manStartPos[maxn];//记录每位男生选取的是心目中第几位的女生
 35 int ladayNow[maxn];//女生对应的男生
 36 
 37 int GetPositionFromLaday(int laday, int man)
 38 {
 39     for(int i=1;i<=n;i++)
 40         if(b[laday][i]==man)
 41             return i;
 42     return -1;
 43 }
 44 
 45 void ChoosePartener(stack<int>& S, int manPos)
 46 {
 47     //选择自己名单上排在首位的女人
 48     int perferLaday = a[manPos][manStartPos[manPos]];
 49     //如果该女孩没有接受过表白,则接受该男孩的表白
 50     if(ladayNow[perferLaday]==-1)
 51     {
 52         ladayNow[perferLaday]=manPos;
 53         ans[manPos]=perferLaday;
 54     }
 55     //如果已经有人向她表白,则判断其现在拥有的有没有现在追求的好
 56     else
 57     {
 58         int oldPos=GetPositionFromLaday(perferLaday,ladayNow[perferLaday]);
 59         int newPos=GetPositionFromLaday(perferLaday,manPos);
 60         if(oldPos<newPos)
 61         {
 62             manStartPos[manPos]++;//说明该女生更喜欢现在拥有的,选心目中第二位
 63             //加入单身行列
 64             S.push(manPos);
 65         }
 66         else //换男友
 67         {
 68             //被甩的男友恢复自由身份
 69             manStartPos[ladayNow[perferLaday]]++;
 70             //加入单身行列
 71             S.push(ladayNow[perferLaday]);
 72             //将追求的男士改为现任男友
 73             ladayNow[perferLaday]=manPos;
 74             ans[manPos]=perferLaday;
 75         }
 76     }
 77 }
 78 
 79 void solve()
 80 {
 81     memset(ladayNow,-1,sizeof(ladayNow));
 82     memset(manStartPos,0,sizeof(manStartPos));
 83     memset(ans,0,sizeof(ans));
 84 
 85     stack<int> S; // 还处于单身的男士
 86 
 87     //进行第一轮迭代,每个男生都选择自己名单上排在首位的女生。
 88     for(int i=1;i<=n;i++) ChoosePartener(S,i);
 89 
 90     while(S.size()!=0)
 91     {
 92         int manPos=S.top();S.pop();
 93         ChoosePartener(S,manPos);
 94     }
 95 }
 96 
 97 int main()
 98 {
 99     //freopen("data.in","r",stdin);
100     //freopen("data.out","w",stdout);
101     //clock_t st=clock();
102     int T;scanf("%d",&T);
103     while(T--)
104     {
105         scanf("%d",&n);char c;
106         man.clear();woman.clear();turn.clear();
107         for(int i=1;i<=n;i++)
108         {
109             getchar();scanf("%c",&c);
110             man[c]=i;temp[i]=c;
111         }
112         for(int i=1;i<=n;i++)
113         {
114             getchar();scanf("%c",&c);
115             woman[c]=i;turn[i]=c;
116         }
117         for(int i=1;i<=n;i++)
118         {
119             getchar();
120             scanf("%c:",&c);int t=man[c];
121             for(int j=0;j<n;j++)
122             {
123                 scanf("%c",&c);
124                 a[t][j]=woman[c];
125             }
126         }
127         for(int i=1;i<=n;i++)
128         {
129             getchar();
130             scanf("%c:",&c);int t=woman[c];
131             for(int j=0;j<n;j++)
132             {
133                 scanf("%c",&c);
134                 b[t][j]=man[c];
135             }
136         }
137         solve();
138         sort(temp+1,temp+1+n);
139         for(int i=1;i<=n;i++)
140         {
141             printf("%c %c
",temp[i],turn[ans[man[temp[i]]]]);
142         }
143         if(T!=0) printf("
");
144     }
145     //clock_t ed=clock();
146     //printf("

Time Used : %.5lf Ms.
",(double)(ed-st)/CLOCKS_PER_SEC);
147     return 0;
148 }
原文地址:https://www.cnblogs.com/CtrlKismet/p/6840930.html