HDU 1522 Marriage is Stable【稳定婚姻】
题意: 有 N 个男生和 N 个女生,已知每个男生对每个女生的喜欢程度,和每个女生对每个男生的喜欢程度。
找到一种搭配方式使得总的满意程度最高。
稳定婚姻解法:
如果男A与女C匹配,男B与女D 匹配,但是A更喜欢D,D更喜欢A,那么这个婚姻就不是稳定的。稳定婚姻问题的算法步骤大致如下:(男士优先)
1.男士先选择自己最爱的人去求婚,如果有多个男士的最爱相同,那么女士就选择更爱的那位男士,那么其他的男士在这次求婚中失败。
2.上次求婚失败的男士再选择自己次爱的女士进行求婚,如果这位女士没有匹配男士,那么这两个人就进行匹配,如果这位女士有匹配的男士,但是如果这位女士更喜欢这位正在求婚的男士,那么这位女士就可以抛弃原有的男士而与这位她更爱的男士匹配。而原有的男士在这次匹配中失败。
3.上次求婚失败的男士(包括被女士抛弃的男士)再次选择自己次爱的女士求婚,知道所有的男士与女士全部匹配则结束。
次算法被证明必定存在解,刚才所写的步骤是基于男士优先的。如果是女士向男士求婚,那么就是基于女士优先的,算法步骤和上面的基本相同,只要将男女调换就可以了。
#include<stdio.h> #include<string.h> #include<string> #include<map> #include<iostream> #include<algorithm> #define maxn 555 #define clr(x)memset(x,0,sizeof(x)) using namespace std; int tot; int n; int b[maxn][maxn]; int g[maxn][maxn]; int by[maxn],gl[maxn]; int r[maxn]; char s[100]; string bo[maxn],gi[maxn]; int main() { int bn,gn,t,flag,i,j,f; while(scanf("%d",&n)!=EOF) { f=0; getchar(); gn=1; clr(b); clr(g); for(i=1;i<=n;i++)r[i]=1; map<string,int>boy,girl; boy.clear(),girl.clear(); tot=1; for(i=1;i<=n;i++) { scanf("%s",s); boy[s]=i; bo[i]=s; for(j=1;j<=n;j++) { scanf("%s",s); if(!girl[s]) { girl[s]=j; gi[j]=s; b[i][j]=j; } else b[i][j]=girl[s]; } } for(i=1;i<=n;i++) { scanf("%s",s); t=girl[s]; for(j=1;j<=n;j++) { scanf("%s",s); g[t][boy[s]]=n-j; } } clr(by); clr(gl); while(1) { flag=1; for(i=1;i<=n;i++) if(!by[i]) { t=b[i][r[i]++]; if(!gl[t]) { by[i]=t; gl[t]=i; } else if(g[t][gl[t]]<g[t][i]) { by[gl[t]]=0; gl[t]=i; by[i]=t; } flag=0; } if(flag) break; } for(i=1;i<=n;i++) cout<<bo[i]<<' '<<gi[by[i]]<<endl; printf("\n"); } return 0; }