Marriage is Stable
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 438 Accepted Submission(s): 257
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]).
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.
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.
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
Author
CHENG, Long
Source
Recommend
8600
stable marriage problem, 用 Gale-Shapley Algorithm, 即
Propose-and-reject algorithm 求婚-拒绝算法 ,即每次单身汉按喜欢程度递减的顺序向女士表白,女士根据自己的喜欢偏好选择汉子,最终得到稳定的男女配对。
简单说明,
1.假设男士A最终与B配对,C与D配对,但A相对B更喜欢D,则A肯定被D拒绝过,且D相对A更喜欢C,所以B是A可得且喜欢程度最高的妹子;
2.假设girl B 相对A更喜欢C, 则C未向B表白过,否则就拒绝/抛弃B了,再综合考虑向B表白过的汉子,A是她的最佳选择,这么看来配对比较稳定。。。
AC代码:(详细注释。。。)
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cmath> #include<vector> #include<cstdlib> #include<algorithm> #include<map> #include<queue> using namespace std; #define LL long long #define ULL unsigned long long #define UINT unsigned int #define MAX_INT 0x7fffffff #define MAX_LL 0x7fffffffffffffff #define MAX(X,Y) ((X) > (Y) ? (X) : (Y)) #define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) #define MAXN 555 int pref[MAXN][MAXN], fb[MAXN], fw[MAXN]; queue<int> q; //光棍队列 map<string, int> m; string manname[MAXN], womanname[MAXN]; int cntman, cntwoman, nxt[MAXN]; //man数量,woman数量,下一个最喜欢的人 int order[MAXN][MAXN], n; const int male=0, female=1; int ID(string s, int &cnt){ //hash 字符串到数字 return (m.count(s) ? m[s] : m[s]=cnt++); } void engage(int man, int woman){ int m=fb[woman]; if(m) q.push(m), fw[m]=0; //如果有未婚夫,抛弃 fw[man]=woman; fb[woman]=man; } void solve(){ memset(fw, 0, sizeof(fw)); memset(fb, 0, sizeof(fb)); while(!q.empty()){ int man=q.front(); q.pop(); int woman=pref[man][nxt[man]++]; if(!fb[woman]) engage(man, woman); //没有未婚夫 else if(order[woman][fb[woman]]>order[woman][man]) engage(man, woman); //出现更迷人的汉子 else q.push(man); } for(int i=1; i<=n; i++) cout<<manname[i]<<' '<<womanname[fw[i]]<<endl; } //test是个debug函数 void test(){ for(int i=1; i<cntman; i++){ cout<<"man "<<i<<": "; cout<<manname[i]<<' '; cout<<(m.count(manname[i]))<<endl; } cout<<"woman:"<<endl; for(int i=1; i<cntwoman; i++){ cout<<"woman "<<i<<": "; cout<<womanname[i]<<' '; cout<<(m.count(womanname[i]))<<endl; } } int main(){ //freopen("C:\Users\Administrator\Desktop\in.txt","r",stdin); while(cin>>n){ getchar(); int i,j; m.clear(); cntman=1; cntwoman=1; string s; char ch; for(i=1; i<=n; i++){ getline(cin, s, ' '); int k=ID(s, cntman); //hash汉子名字到编号,易处理 manname[k]=s; for(j=1; j<=n; j++){ ch=(j==n ? ' ' : ' '); getline(cin, s, ch); pref[k][j]=ID(s, cntwoman); //汉子k第j喜欢的妹子为ID(...) } q.push(k); nxt[k]=1; } for(i=1; i<=n; i++){ getline(cin, s, ' '); int k=ID(s, cntwoman); womanname[k]=s; for(j=1; j<=n; j++){ ch=(j==n ? ' ' : ' '); getline(cin, s, ch); int t=ID(s, cntman); order[k][t]=j; //妹子k第j喜欢的汉子是t } } if(cntman == cntwoman) solve(); //这里会存在光棍/剩女的可能 else cout<<"Impossible"<<endl; // test(); cout<<endl; } return 0; }