1、婚姻稳定问题描述:
有n个男人,n个女人,每个男人对每个女人之间都有一个好感度,
每个女人对每个男人也有一个好感度,求一种最佳方案,让男人,女人配对,
每个男人会去追求每个女生,使总体的好感度最高,
就是使她们的结合最稳定,就是婚姻稳定问题。
2、解决方法:
从为配对的男人开始,寻找最合适他的女人,
如果当前找的女人已经有男人了,判断这个女人对这两个男人的那个好感度更高,
然后将他配对。
当所有的男人都配对时,算法结束。
(之前看蓝书上的分析,说婚姻匹配最终能让所有男人选到最心仪的女人,但是女人不一定能和自己最心仪的男人结婚,
因为有可能她最喜欢的男生可能永远也没有向他告白,所以主动一点还是有好的)
3、例题分析:
简单的,直接上模板
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 50;
int bh1[220],bh2[220],v1[maxn],v2[maxn],m1[maxn][maxn],m2[maxn][maxn],n,rk[maxn];
int a1[maxn],a2[maxn];
void fun(){
for(int i=1;i<=n;i++){
v1[i] = v2[i] = 0;
rk[i] = 0;
}
while(1){
int fg = 0;
for(int i=1;i<=n;i++)
if(!v1[i]){ //找一个单身的男人
fg = 1;
int g = m1[i][++rk[i]];
if(!v2[g]){ //当这个女人也单身的时候
v1[i] = g;//记录每个男人所配对的女人
v2[g] = i; //记录每个女人所配对的男人
}
else if(m2[g][i]>m2[g][v2[g]]){ //当这个女人遇到比之前更喜欢的男人时
v1[v2[g]] = 0;
v1[i] = g;
v2[g] = i;
}
}
if(!fg) break;
}
for(int i=1;i<=n;i++)
printf("%c %c\n",a1[i],a2[v1[i]]);
}
int main(void){
int T;scanf("%d",&T);
while(T--){
memset(bh1,0,sizeof(bh1));
memset(bh2,0,sizeof(bh2));
scanf("%d",&n);
for(int i=1;i<=n;i++){
char ss[3];scanf("%s",ss);
bh1[ss[0]] = i;
a1[i] = ss[0];
}
for(int i=1;i<=n;i++){
char ss[3];scanf("%s",ss);
bh2[ss[0]] = i;
a2[i] = ss[0];
}
for(int i=1;i<=n;i++){
char ss[maxn];
scanf("%s",ss);
int x = bh1[ss[0]],len = strlen(ss);
for(int j=2;j<len;j++){
int y = bh2[ss[j]];
m1[x][j-1] = y; //记录男人x喜欢的女人y,喜欢程度从高到低
}
}
for(int i=1;i<=n;i++){
char ss[maxn];
scanf("%s",ss);
int x = bh2[ss[0]],len = strlen(ss);
for(int j=2;j<len;j++){
int y = bh1[ss[j]];
m2[x][y] = n-(j-1)+1; //记录女人x喜欢的男人y,喜欢程度越高,m2[x][y]的值越高
}
}
fun();
if(T>0) printf("\n");
}
return 0;
}
用mp记录每个男人和女人的编号即可
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
using namespace std;
const int maxn = 505;
int v1[maxn],v2[maxn],m1[maxn][maxn],m2[maxn][maxn],t1,t2,rk[maxn],n;
map <string,int> mp1,mp2;
string s1[maxn],s2[maxn];
void Init(){
for(int i=1;i<=n;i++){
v1[i] = v2[i] = 0;
rk[i] = 0;
m1[i][0] = m2[i][0] = 0;
}
t1 = t2 = 0;
mp1.clear();mp2.clear();
}
int ID1(string ss){
if(!mp1.count(ss)){
mp1[ss] = ++t1;
s1[t1] = ss;
}
return mp1[ss];
}
int ID2(string ss){
if(!mp2.count(ss)){
mp2[ss] = ++t2;
s2[t2] = ss;
}
return mp2[ss];
}
void fun(){
while(1){
int fg = 0;
for(int i=1;i<=n;i++)
if(!v1[i]){
fg = 1;
int g = m1[i][++rk[i]];
if(!m1[i][g]){
v1[i] = g;
v2[g] = i;
}
else if(m2[g][i]>m2[g][v2[g]]){
v1[v2[g]] = 0;
v1[i] = g;
v2[g] = i;
}
}
if(!fg) break;
}
for(int i=1;i<=n;i++)
cout<<s1[i]<<" "<<s2[v1[i]]<<endl;
}
int main(void){
while(cin>>n){
Init();
for(int i=1;i<=n;i++){
string ss;
cin>>ss;
int x = ID1(ss);
for(int j=1;j<=n;j++){
cin>>ss;
int y = ID2(ss);
m1[x][++m1[x][0]] = y;
}
}
for(int i=1;i<=n;i++){
string ss;
cin>>ss;
int x = ID2(ss);
for(int j=1;j<=n;j++){
cin>>ss;
int y = ID1(ss);
m2[x][y] = n-j+1;
}
}
fun();
}
return 0;
}
先求距离,按照距离,容量排序再去求解。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn = 202;
double dis[maxn];
int n,ro1[maxn],ro2[maxn],v1[maxn],v2[maxn],m1[maxn][maxn],rk[maxn],id[maxn],m2[maxn][maxn];
struct Node{
int id;
double x,y,z;
};
Node c1[maxn],c2[maxn];
bool cmp(int x,int y){
if(dis[x]==dis[y]) return ro1[x]>ro1[y];
return dis[x]<dis[y];
}
bool tmp(int x,int y){
if(dis[x]==dis[y]) return ro2[x]>ro2[y];
return dis[x]<dis[y];
}
double f(Node a,Node b){
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z));
}
void fun(){
for(int i=1;i<=n;i++){
v1[i] = v2[i] = 0;
rk[i] = 0;
}
while(true){
int fg = 0;
for(int i=1;i<=n;i++)
if(!v1[i]){
fg = 1;
int g = m1[i][++rk[i]];
if(!v2[g]){
v2[g] = i;
v1[i] = g;
}
else if(m2[g][i]>m2[g][v2[g]]){
v1[v2[g]] = 0;
v1[i] = g;
v2[g] = i;
}
}
if(!fg) break;
}
for(int i=1;i<=n;i++)
printf("%d %d\n",c1[v2[i]].id,c2[i].id);
}
int main(void){
int T;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=1;i<=n;i++){
int x;
scanf("%d",&c1[i].id);
scanf("%lf",&ro1[i]);
scanf("%lf%lf%lf",&c1[i].x,&c1[i].y,&c1[i].z);
}
for(int i=1;i<=n;i++){
int x;
scanf("%d",&c2[i].id);
scanf("%lf",&ro2[i]);
scanf("%lf%lf%lf",&c2[i].x,&c2[i].y,&c2[i].z);
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
dis[j] = f(c1[i],c2[j]);
id[j] = j;
}
sort(id+1,id+n+1,tmp);
for(int j=1;j<=n;j++){
m1[i][j] = id[j];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
dis[j] = f(c2[i],c1[j]);
id[j] = j;
}
sort(id+1,id+n+1,cmp);
for(int j=1;j<=n;j++){
m2[i][id[j]] = n-j+1;
}
}
fun();
}
return 0;
}