<题目链接>
题目大意:
给你N个男生和N个女生,并且给出所有男生和女生对其它所有异性的喜欢程度,喜欢程度越高的两个异性越容易配对,现在求出它们之间的稳定匹配。
解题分析:
稳定婚姻问题的模板题,需要用到Gale_Shapley算法,GS算法讲解 >>>
这个算法还是很直观的。
1 #include <iostream> 2 #include <cstring> 3 #include <stack> 4 #include <string> 5 #include <map> 6 #include <algorithm> 7 using namespace std; 8 9 #define N 505 10 #define clr(a,b) memset(a,b,sizeof(a)) 11 #define rep(i,s,t) for(int i=s;i<=t;i++) 12 13 int n,getmp_boy[N][N],getmp_girl[N][N],boy[N],girl[N],rnk[N]; 14 map<string,int>mp_boy,mp_girl; 15 string s,name_boy[N],name_girl[N]; 16 17 void Gale_Shapley(){ 18 clr(boy,0);clr(girl,0); 19 rep(i,1,n) rnk[i]=1; 20 while(true){ 21 bool flag=false; 22 rep(i,1,n){ 23 if(!boy[i]){ 24 int x=getmp_boy[i][rnk[i]++]; //x为当前男生所最求的他没有尝试最求过的最喜欢的女生 25 if(!girl[x]){ //如果这个女生没有和男生配对 26 boy[i]=x; //那么这对男女进行配对 27 girl[x]=i; 28 }else if(getmp_girl[x][i] > getmp_girl[x][girl[x]]){ //如果当前女生已经配对,那么就判断她对这两个男生的喜欢程度 29 boy[girl[x]]=0; //将原来的男生抛弃 30 girl[x]=i; //将这两个男女进行配对 31 boy[i]=x; 32 } 33 flag=true; 34 } 35 } 36 if(!flag)break; //如果所有男生都已配对,则直接退出 37 } 38 rep(i,1,n) cout<<name_boy[i]<<" "<<name_girl[boy[i]]<<endl; 39 } 40 41 int main(){ 42 ios_base::sync_with_stdio(false); 43 cin.tie(0);cout.tie(0); 44 while(cin>>n){ 45 mp_boy.clear();mp_girl.clear(); 46 int pos=1,tmp; 47 rep(i,1,n){ 48 cin>>s;name_boy[i]=s; 49 mp_boy[s]=i; 50 rep(j,1,n){ 51 cin>>s;tmp=mp_girl[s]; 52 if(!tmp){ //对于之前没有出现过个的女生姓名,重新分配序号 53 tmp=pos++; 54 mp_girl[s]=tmp; 55 name_girl[tmp]=s; 56 } 57 getmp_boy[i][j]=tmp; //记录第i个男生第j个喜欢的女生是tmp 58 } 59 } 60 rep(i,1,n){ 61 cin>>s;int x=mp_girl[s]; 62 rep(j,1,n){ 63 cin>>s;int y=mp_boy[s]; 64 getmp_girl[x][y]=n-j; //记录第i个女生喜欢男生y的程度是n-j 65 } 66 } 67 Gale_Shapley(); 68 } 69 }
2019-01-17