又是图论-稳定婚姻算法的C++实现
2014-03-19 19:11
190 查看
稳定婚姻是一个很有意思的二分图问题,这在生活中是一个典型的问题,通俗地可叙述为:当前有N位男生和N位女生最后要组成稳定的婚姻家庭,过程开始之前男生和女生在各自的心目中都按照喜爱程度对N位异性有了各自的排序.然后开始选择自己的对象,目的是让所有的人都能找到最适合的对象:下面是我的C++代码实现:
下面是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)的,这里似乎并没有什么优化的可能了,不过,也很容易看到,这种算法是具有性别歧视的,不过这是这种算法本身的缺陷,也没有什么改善的可能了。
#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)的,这里似乎并没有什么优化的可能了,不过,也很容易看到,这种算法是具有性别歧视的,不过这是这种算法本身的缺陷,也没有什么改善的可能了。
相关文章推荐
- 稳定婚姻匹配 G-S算法 JAVA和C++实现
- 仿真算法数据结构与算法 C++实现
- A star 寻路算法实现(C++版本)
- 程序员代码面试指南:IT名企算法与数据结构题目最优解-字符串问题:C/C++语言实现
- 摘:数据结构各种算法实现(C++模板)
- 插入排序算法之C++实现
- 【PSO】一个C++的粒子群(PSO)算法实现
- 浅谈稳定完备婚姻的算法
- 图的深度优先搜索和广度优先搜索算法、最小生成树两种算法 --C++实现
- 金融系统中PBOC/EMV的TLV的算法实现(含C++/C#)
- 寻找第k大或第k小的算法 -- 内存足够(C++实现)
- 经典算法与数据结构的c++实现——直接选择排序
- 图的点对最短路径算法(C++实现)
- 【算法和数据结构】分治思想之二分查找(C++实现)
- C++实现的大数相乘算法示例
- hdu 1233 还是畅通工程(最小生成树的Prim和Kruskal两种算法的c++实现)(prim算法详解)
- C++ 基本算法 冒泡法、交换法、选择法、实现代码集合
- 场景管理:BSP算法C++实现
- 数据结构各种算法实现(C++模板)
- c++实现"四分位数"算法1