二分图最大权完美匹配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个字符串,若两两相连,将前一个反置添加到后一个后面,相连的值为两个字串从头开始相等的字符个数: 问如何匹配得出最大值: 思路:建图,套模板. 代码: # ...
随机推荐
- 513 Find Bottom Left Tree Value 找树左下角的值
给定一个二叉树,在树的最后一行找到最左边的值. 详见:https://leetcode.com/problems/find-bottom-left-tree-value/description/ C+ ...
- 508 Most Frequent Subtree Sum 出现频率最高的子树和
详见:https://leetcode.com/problems/most-frequent-subtree-sum/description/ C++: /** * Definition for a ...
- git分支提交管理
随着需求的增多,为了多人协作的顺利进行,需要进行分支开发,进而带来分支管理问题.今天主要讲一下如何管理分支及提交. 为了使git更好用,下面是我的git配置文件(放在C:\Users\Administ ...
- 微信小程序九宫格布局
先上效果图 使用注意事项 1:注意在app.json中注册页面路径 2:如果要增加新的Item,可到js中对listService数组进行增加 3:listService参数[ title:分类标题 ...
- [BZOJ1050][HAOI2006]旅行comf 枚举+并查集
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1050 将边排序,枚举边权最小的边,依次加边直到S和T连通,更新答案. #include&l ...
- ES6学习笔记(3)----字符串的扩展
参考书<ECMAScript 6入门>http://es6.ruanyifeng.com/ 字符串的扩展ES6之前只能识别\u0000 - \uFFFF 之间的字符,超过此范围,识别会出错 ...
- jsp <%@ include %> 例子
<%@ include %>:所有代码包含进来之后一起进行处理,最终编译成一个servlet. jsp文件中添加top和bottom.jsp页面 empList.jsp <%@ pa ...
- JavaScript-基础类型和运算符
JavaScript-基础类型和运算符 P02.稍微了解 1.js代码需要编写到script标签中 <script type="text/javascript"> 此处 ...
- upload 上传按钮组件 iview
<!-- * @description 导入Excel * @fileName importExcel.vue * @author 彭成刚 * @date // :: * @version V1 ...
- Java数据结构和算法(一)--栈
栈: 英文名stack,特点是只允许访问最后插入的那个元素,也就是LIFO(后进先出) jdk中的stack源码: public class Stack<E> extends Vector ...