穩定婚姻是一個很有意思的二分圖問題,這在生活中是一個典型的問題,通俗地可敘述爲:當前有N位男生和N位女生最後要組成穩定的婚姻家庭,過程開始之前男生和女生在各自的心目中都按照喜愛程度對N位異性有了各自的排序.然後開始選擇自己的對象,目的是讓所有的人都能找到最適合的對象:下面是我的C++代碼實現:
#include<iostream>
#include<queue>
#include<vector>
#include<stdio.h>
using namespace std;
struct woman{
bool free;
vector<int>v;
int h ;
};
struct best_woman
{
int num; //編號
int Rank; //排名
best_woman(int n,int i):num(n),Rank(i){}
friend bool operator <(best_woman w1,best_woman w2)
{
return w1.Rank>w2.Rank;
}
};
struct man{
bool free ;
priority_queue<best_woman>v;
};
class marry
{
private:
int n;
vector<man>M;
vector<woman>WM;
public:
marry(int n):n(n)
{
man mtmp;
woman wmtmp;
for(int i=0;i<=n;i++) //n個男士,從1開始,女士一樣
{
M.push_back(mtmp);
WM.push_back(wmtmp);
M[i].free=1;
WM[i].free=1;
WM[i].v.push_back(0);
}
}
void man_priority(int j,int i,int Rank) //第j個男士對第i個女士的排名
{
best_woman wtmp(i,Rank);
M[j].v.push(wtmp);
}
void woman_priority(int j,int Rank)
{
WM[j].v.push_back(Rank);
}
void m_marry()
{
queue<int>Q;
for(int i=1;i<=n;i++)
Q.push(i);
while(!Q.empty())
{
int m=Q.front();Q.pop();
best_woman bw=M[m].v.top();M[m].v.pop();
int w=bw.num;
if(WM[w].free)
{
WM[w].free=0;
WM[w].h=m;
}
else if(WM[w].v[WM[w].h]>WM[w].v[m])
{
Q.push(WM[w].h);
WM[w].h=m;
}
else
Q.push(m);
}
}
void print()
{
for(int i=1;i<=n;i++)
cout<<"woman "<<i<<",man "<<WM[i].h<<endl;
}
};
int main()
{
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
int n;
while(cin>>n)
{
marry M(n);
int tmp;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
cin>>tmp;
M.man_priority(i,j,tmp);
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
cin>>tmp;
M.woman_priority(i,tmp);
}
M.m_marry();
M.print();
cout<<endl;
}
fclose(stdin);
fclose(stdout);
return 0;
}
下面是in.txt的測試數據:
3
2 1 3
3 1 2
3 2 1
3 1 2
2 3 1
3 1 2
2
1 2
2 1
2 1
1 2
4
1 2 3 4
1 4 3 2
2 1 3 4
4 2 3 1
3 4 2 1
3 1 4 2
2 4 3 1
3 2 1 4
然後是out.txt的結果,如下:
woman 1,man 1
woman 2,man 3
woman 3,man 2
woman 1,man 1
woman 2,man 2
woman 1,man 3
woman 2,man 4
woman 3,man 1
woman 4,man 2
可以看到,程序沒有什麼問題,這個算法的核心是有男士先按照自己的優先列表去挑選女士,然後女士再根據自己的列表和已經被告白的男士來看是否要接受這位男士,由於我用的是優先隊列這種數據結構,所以整個算法的效率是O(n^2logn)的,當然,空間效率是O(n^2)的,這裏似乎並沒有什麼優化的可能了,不過,也很容易看到,這種算法是具有性別歧視的,不過這是這種算法本身的缺陷,也沒有什麼改善的可能了。