hdu1914 稳定婚姻问题
稳定婚姻问题就是给你n个男的,n个女的,然后给你每个男生中女生的排名,和女生心目中男生的排名,然后让你匹配成n对,使婚姻稳定,假如a和b匹配,c和d匹配,如果a认为d比b好,同时d也认为a比c好,那么ad就有可能私奔,这样就导致了婚姻的不稳定,稳定婚姻就是找到一种解决方案让婚姻稳定
算法:
稳定婚姻的解决方法比较简单,通俗易懂,而且还容易实现,具体有没有固定的模板我不知道,没有去找,自己模拟的,在求解的过程中,我们先把所有的男生都加到队列里,队列里的就表示当前还单身的男生,每次从队列里拿出一个男生,然后从她最喜欢的女生开始匹配,如果当前的女生尝试追求过,那么就不用追求了,如果当前的女生没有伴侣,那么可以直接匹配上,如果有伴侣,那么就看看当前这个男生和女生之前的伴侣在那个女生中更喜欢谁,如果更喜欢当先的这个男生,那么当前男生就和这个女生匹配,女生之前匹配过的直接变成单身,被扔回队列,否则,继续找下一个女生,知道找到一个能匹配上的为止,就这样一直到队列空的时候,就已经全部匹配完成了。
正确性:
对于男生来说,每次都是从最喜欢的女生开始匹配的,遇到的第一个没人能抢走的并且稳定的就是自己最终伴侣,也就是说如果之前追求过的女生被别人抢走了,那么他将永远抢不会来,因为对于女生来说,第一次被男士按照自己的意愿选择之后,每次变更匹配对象都是在自己心目中更加喜欢的,所以一旦他放弃了某个男生,那么那个男生就没希望在和他匹配,这样男生是从最优的选的,保证男生不会出轨,女生每次都是在选择她的男生中选择最优的,这样也保证了女生最后没有怨言,这样的话,最后的到的婚姻就是稳定的,至于稳定婚姻,肯定会有稳定方案,这个我暂时证明不了.<1962年,美国数学家
David Gale 和 Lloyd Shapley是这两个人发明的方法,并且证明了稳定婚姻一定会有解>。
#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
#define N 30
using namespace std;
typedef struct
{
char a ,b;
}NODE;
NODE Ans[N];
int map[N][N] ,G_b[N][N];
int nowb[N] ,nowg[N];
char nameb[N] ,nameg[N];
int mark[N][N] ,ID[200];
bool camp(NODE a ,NODE b)
{
return a.a < b.a;
}
void Marr(int n)
{
queue<int>q;
for(int i = 1 ;i <= n ;i ++)
q.push(i);
memset(mark ,0 ,sizeof(mark));
memset(nowb ,255 ,sizeof(nowb));
memset(nowg ,255 ,sizeof(nowg));
while(!q.empty())
{
int xin ,tou = q.front();
q.pop();
for(int i = 1 ;i <= n ;i ++)
{
xin = map[tou][i];
if(mark[tou][xin]) continue;
mark[tou][xin] = 1;
if(nowg[xin] == -1)
{
nowg[xin] = tou;
nowb[tou] = xin;
break;
}
else
{
if(G_b[xin][tou] > G_b[xin][nowg[xin]])
{
q.push(nowg[xin]);
nowg[xin] = tou;
nowb[tou] = xin;
break;
}
}
}
}
return ;
}
int main ()
{
int t ,n ,i ,j;
char str[30];
scanf("%d" ,&t);
while(t--)
{
scanf("%d" ,&n);
getchar();
for(i = 1 ;i <= n ;i ++)
{
scanf("%s" ,str);
ID[str[0]] = i;
nameb[i] = str[0];
}
for(i = 1 ;i <= n ;i ++)
{
scanf("%s" ,str);
ID[str[0]] = i;
nameg[i] = str[0];
}
for(i = 1 ;i <= n ;i ++)
{
scanf("%s" ,str);
for(j = 2 ;j <= n + 1 ;j ++)
map[ID[str[0]]][j-1] = ID[str[j]];
}
for(i = 1 ;i <= n ;i ++)
{
scanf("%s" ,str);
for(j = 2 ;j <= n + 1 ;j ++)
G_b[ID[str[0]]][ID[str[j]]] = n - j + 2;
}
Marr(n);
for(i = 1 ;i <= n ;i ++)
Ans[i].a = nameb[i] ,Ans[i].b = nameg[nowb[i]];
sort(Ans + 1 ,Ans + n + 1 ,camp);
for(i = 1 ;i <= n ;i ++)
printf("%c %c\n" ,Ans[i].a ,Ans[i].b);
if(t) printf("\n");
}
return 0;
}
hdu1914 稳定婚姻问题的更多相关文章
- HDU1914 稳定婚姻匹配
The Stable Marriage Problem Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (J ...
- 【HDU1914 The Stable Marriage Problem】稳定婚姻问题
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1914 题目大意:问题大概是这样:有一个社团里有n个女生和n个男生,每位女生按照她的偏爱程度将男生排序, ...
- UVA 1175 Ladies' Choice 稳定婚姻问题
题目链接: 题目 Ladies' Choice Time Limit: 6000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu 问题 ...
- BZOJ2140: 稳定婚姻
题解: 题意就是求二分图的必须边. 我们有结论: 在残量网络上跑tarjan,对于一条边(u,v) 如果该边满流||scc[u]==scc[v],那么该边是可行边. 因为如果scc[u]==scc[v ...
- 【POJ 3487】 The Stable Marriage Problem (稳定婚姻问题)
The Stable Marriage Problem Description The stable marriage problem consists of matching members o ...
- 【UVAlive 3989】 Ladies' Choice (稳定婚姻问题)
Ladies' Choice Teenagers from the local high school have asked you to help them with the organizatio ...
- 【稳定婚姻问题】【HDU1435】【Stable Match】
2015/7/1 19:48 题意:给一个带权二分图 求稳定匹配 稳定的意义是对于某2个匹配,比如,( a ---- 1) ,(b----2) , 如果 (a,2)<(a,1) 且(2,a)& ...
- poj 3487 稳定婚姻
/** 稳定婚姻:男生不停的求婚,女生不停地拒绝 **/ #include <iostream> #include <queue> #include <cstdio> ...
- 稳定婚姻问题和Gale-Shapley算法(转)
什么是算法?每当有人问作者这样的问题时,他总会引用这个例子:假如你是一个媒人,有若干个单身男子登门求助,还有同样多的单身女子也前来征婚.如果你已经知道这些女孩儿在每个男孩儿心目中的排名,以及男孩儿们在 ...
随机推荐
- Spring Boot 2.x基础教程:使用MongoDB
前段时间因为团队调整,大部分时间放在了团队上,这系列的更新又耽误了一下.但既然承诺持久更新,那就不会落下,今天开始继续更新这部分的内容! 过了年,重申一下这个系列的目标:目前主要任务就是把Spring ...
- java安全初学之动态代理
前言:作为安全人员,代理大家用的都很多,那什么是java中的动态代理呢?事实上,java中的"动态"也就意味着使用了反射,因此动态代理是基于反射机制的一种代理模式. 简介: 代理是 ...
- C# 应用 - 封装类访问 Mysql 数据库
个人经历的项目主要都是用 Postgresql 或 Oracle 数据库,本文非原创,从他处整理而来. 1. 库类 mysql.data.dll using MySql.Data.MySqlClien ...
- Vulkan移植GpuImage(一)高斯模糊与自适应阈值
自适应阈值效果图 demo 这几天抽空看了下GpuImage的filter,移植了高斯模糊与自适应阈值的vulkan compute shader实现,一个是基本的图像处理,一个是组合基础图像处理聚合 ...
- Go语言学习笔记——Go语言的指针
Go具有指针.指针保存了变量的内存地址. 类型*T是指向类型T的值得指针.其零值是nil var p *int &符号会生成一个指向其作用对象的指针 i:=42 P=&i *符号表示指 ...
- golang 三维向量相关操作
package vector import ( "math" "fmt" )// 三维向量:(x,y,z) type Vector3 struct { X fl ...
- 文本编辑工具 Vim与压缩打包
vim一共有3种模式:一般模式.编辑模式和命令模式 一般模式下的移动光标 光标向左移动:h或者向左的方向键 光标向右移动:l或者向右的方向键光标向上移动:k或者向上的方向键光标向下移动:j或者向下的方 ...
- menuStrip鼠标滑过自动弹出
public partial class FrmMain : Form { public FrmMain() { InitializeComponent(); } private void 退出系统T ...
- C++并发与多线程学习笔记--基本概念和实现
基本概念 并发 可执行程序.进程.线程 学习心得 并发的实现方法 多进程并发 多线程并发 总结 C++标准库 基本概念 (并发.进程.线程)区分C++初级编程和中高级编程 并发 两个或者更多的任务同时 ...
- 通过lms.samples熟悉lms微服务框架的使用
经过一段时间的开发与测试,终于发布了Lms框架的第一个正式版本(1.0.0版本),并给出了lms框架的样例项目lms.samples.本文通过对lms.samples的介绍,简述如何通过lms框架快速 ...