二分图最大权完美匹配KM算法
KM算法二分图
KM求得二分图与普通二分图的不同之处在于:此二分图的每条边(男生女生)上都附了权值(好感度)。然后,求怎样完美匹配使得权值之和最大。
这,不止一般的麻烦啊。
可以通过一个期望值来求。
大致思路就是:
每个男生女生都有期望值,男生一开始全部为0,女生一开始则是可能的最大值。
匹配的条件为男生的期望值加上女生的期望值等于他们之间的权值(好感度)。
每次如果不能匹配,就降一下参加匹配的女生的期望值,加一下参加匹配的男生的期望值。
基本思路就这样,具体参考别人的一篇博客。
代码也是人家的。。。
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int MAXN=;
const int INF=0x3f3f3f3f;
int love[MAXN][MAXN];//记录每个妹子和每个男生的好感度
int ex_girl[MAXN];//每个妹子的期望值
int ex_boy[MAXN];//每个男生的期望值
bool vis_girl[MAXN];//记录每一轮匹配匹配过的女生
bool vis_boy[MAXN];//记录每一轮匹配匹配过的男生
int match[MAXN];//记录每个男生匹配到的妹子 如果没有则为-1
int slack[MAXN];//记录每个汉子如果能被妹子倾心最少还需要多少期望值
int N;
bool dfs(int girl){
vis_girl[girl]=true;
for(int boy=;boy<N;++boy) {
if(vis_boy[boy])
continue;//每一轮匹配 每个男生只尝试一次
int gap=ex_girl[girl]+ex_boy[boy]-love[girl][boy];
if(gap==){//如果符合要求
vis_boy[boy]=true;
if(match[boy]==-||dfs(match[boy])){//找到一个没有匹配的男生 或者该男生的妹子可以找到其他人
match[boy]=girl;
return true;
}
}
else
slack[boy]=min(slack[boy],gap);//slack可以理解为该男生要得到女生的倾心 还需多少期望值 取最小值
}
return false;
}
int KM(){
memset(match,-,sizeof match);//初始每个男生都没有匹配的女生
memset(ex_boy,,sizeof ex_boy);//初始每个男生的期望值为0
//每个女生的初始期望值是与她相连的男生最大的好感度
for(int i=;i<N;++i){
ex_girl[i]=love[i][];
for(int j=;j<N;++j)
ex_girl[i]=max(ex_girl[i],love[i][j]);
}
//尝试为每一个女生解决归宿问题
for(int ii=;ii<N;++ii){
fill(slack,slack+N,INF);//因为要取最小值 初始化为无穷大
while(){
//为每个女生解决归宿问题的方法是:如果找不到就降低期望值,直到找到为止
//记录每轮匹配中男生女生是否被尝试匹配过
memset(vis_girl,false,sizeof vis_girl);
memset(vis_boy,false,sizeof vis_boy);
if(dfs(ii))
break;//找到归宿 退出
//如果不能找到 就降低期望值
int d=INF;//最小可降低的期望值
for(int j1=;j1<N;++j1)
if(!vis_boy[j1])
d=min(d,slack[j1]);
for(int j2=;j2<N;++j2){
//所有访问过的女生降低期望值
if(vis_girl[j2])
ex_girl[j2]-=d;
//所有访问过的男生增加期望值
if(vis_boy[j2])
ex_boy[j2]+=d;
//没有访问过的boy 因为girl们的期望值降低,距离得到女生倾心又进了一步!
else
slack[j2]-=d;
}
}
}
//匹配完成 求出所有配对的好感度的和
int res=;
for(int iii=;iii<N;++iii)
res+=love[match[iii]][iii];
return res;
}
int main(){
scanf("%d",&N);
for(int i=;i<N;++i)
for(int j=;j<N;++j)
scanf("%d",&love[i][j]);
printf("%d\n",KM());
return ;
}
具体实现过程还是得自己理解,实在不行就自己调试几遍,提供一个数据:
直接就是那篇博客的图。
二分图最大权完美匹配KM算法的更多相关文章
- 【模板】二分图最大权完美匹配KM算法
hdu2255模板题 KM是什么意思,详见百度百科. 总之知道它可以求二分图最大权完美匹配就可以了,时间复杂度为O(n^3). 给张图. 二分图有了边权,求最大匹配下的最大权值. 所以该怎么做呢?对啊 ...
- 二分图最大权值匹配 KM算法 模板
KM算法详解+模板 大佬讲的太好了!!!太好了!!! 转载自:http://www.cnblogs.com/wenruo/p/5264235.html KM算法用来求二分图最大权完美匹配. 本文配合该 ...
- HDU2255-奔小康赚大钱-二分图最大权值匹配-KM算法
二分图最大权值匹配问题.用KM算法. 最小权值的时候把权值设置成相反数 /*-------------------------------------------------------------- ...
- 【二分图最大权完美匹配】【KM算法】【转】
[文章详解出处]https://www.cnblogs.com/wenruo/p/5264235.html KM算法是用来求二分图最大权完美匹配的.[也就算之前的匈牙利算法求二分最大匹配的变种??] ...
- 【模板】二分图最大权完美匹配(KM算法)/洛谷P6577
题目链接 https://www.luogu.com.cn/problem/P6577 题目大意 给定一个二分图,其左右点的个数各为 \(n\),带权边数为 \(m\),保证存在完美匹配. 求一种完美 ...
- Solution -「洛谷 P6577」「模板」二分图最大权完美匹配
\(\mathcal{Description}\) Link. 给定二分图 \(G=(V=X\cup Y,E)\),\(|X|=|Y|=n\),边 \((u,v)\in E\) 有权 \(w( ...
- 二分图学习记 之 KM算法 二分图最大权完美匹配。
前置知识 :匈牙利算法 首先有这样一张图,求这张图的最大权完美匹配. 当然如果你不想看这些渣图的话,您可以转到 洛谷 运动员最佳匹配问题 下面我来强行解释一下KM算法 左边一群妹子找汉子,但是每个妹子 ...
- uva 1411 Ants (权值和最小的完美匹配---KM算法)
uva 1411 Ants Description Young naturalist Bill studies ants in school. His ants feed on plant-louse ...
- hdu 3722 二分图 最优完备匹配 KM算法
这题只要想到是最优完备匹配就行了: 题意:给出n个字符串,若两两相连,将前一个反置添加到后一个后面,相连的值为两个字串从头开始相等的字符个数: 问如何匹配得出最大值: 思路:建图,套模板. 代码: # ...
随机推荐
- 记录两个python itchat的用法博客网址
http://www.tuicool.com/articles/VJZRRfn https://itchat.readthedocs.io/zh/latest/
- css新奇技术及其未来发展
1.图像替换技术: 图像替换技术是指使用图像替换页面中文本的功能,类似与在页面中插入图像,只是这种方法更为方便,易于代码管理.通常来说,设计者习惯使用有意义的图像去替换一些标题,logo和某些特定的页 ...
- C51之数据范围
在C51中各数据类型的范围如下:如果宏常量大于65536,则要加UL后缀:乘法运算不能只将结果强制类型转换,而应在被乘数前加(unsigned long)强制转换. 2 因为RAM有限,所以运算量大的 ...
- D. Black Hills golden jewels 二分答案 + 二分判定
http://codeforces.com/gym/101064/problem/D 题目是给定一个数组,如果两两组合,有C(n, 2)种结果,(找出第一个大于等于第k大的结果) 思路, 二分答案va ...
- AJPFX关于学习java遇到的问题:对算法和数据结构不熟悉
为什么我先拿“数据结构和算法”说事捏?这玩意是写程序最最基本的东东.不管你使用 Java 还是其它的什么语言,都离不开它.而且这玩意是跨语言的,学好之后不管在哪门语言中都能用得上. 既然“数据结构和算 ...
- 获取第三方软件的包名、入口Activity的类名
要启动指定的第三方软件,需要知道第三方软件的包名.类名. 获取第三方软件包名.类名的两种方法: 1.使用aapt aapt是sdk自带一个工具,在 Sdk\builds-tools 目录下 .如果没有 ...
- UISegmentedControl去掉背景色与UIScrollView联动
UISegmentControl分段控制器是UIKit框架提供的一组按钮栏,提供多个可选的按钮,只能激活其中的一个,响应事件.主要用来在同一层次重要性下不同的信息展示或者不同的界面展示之间切换.例如手 ...
- pspad的一个怪现象:在一些空行的位置出现个别不该出现的字符
在用pspad编辑一个外来文件时,发现有许多空行的结尾会出现一些单个字符,字符内容与翻页前那一页相应位置的字符相同. 好奇怪.上网找不到原因.pspad太好用了,不想因此放弃. 仔细观察,这些空行往往 ...
- (转)Spring的bean管理(注解方式)
http://blog.csdn.net/yerenyuan_pku/article/details/69663779 Spring的bean管理(注解方式) 注解:代码中的特殊标记,注解可以使用在类 ...
- ElasticSearch的常用方法
关键词 cluster 集群 shards 索引分片 replicas 索引的副本 recovery 数据重新分布 gateway 索引的持久化方式 Transport 交互 ...