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算法的更多相关文章

  1. 【模板】二分图最大权完美匹配KM算法

    hdu2255模板题 KM是什么意思,详见百度百科. 总之知道它可以求二分图最大权完美匹配就可以了,时间复杂度为O(n^3). 给张图. 二分图有了边权,求最大匹配下的最大权值. 所以该怎么做呢?对啊 ...

  2. 二分图最大权值匹配 KM算法 模板

    KM算法详解+模板 大佬讲的太好了!!!太好了!!! 转载自:http://www.cnblogs.com/wenruo/p/5264235.html KM算法用来求二分图最大权完美匹配. 本文配合该 ...

  3. HDU2255-奔小康赚大钱-二分图最大权值匹配-KM算法

    二分图最大权值匹配问题.用KM算法. 最小权值的时候把权值设置成相反数 /*-------------------------------------------------------------- ...

  4. 【二分图最大权完美匹配】【KM算法】【转】

    [文章详解出处]https://www.cnblogs.com/wenruo/p/5264235.html KM算法是用来求二分图最大权完美匹配的.[也就算之前的匈牙利算法求二分最大匹配的变种??] ...

  5. 【模板】二分图最大权完美匹配(KM算法)/洛谷P6577

    题目链接 https://www.luogu.com.cn/problem/P6577 题目大意 给定一个二分图,其左右点的个数各为 \(n\),带权边数为 \(m\),保证存在完美匹配. 求一种完美 ...

  6. Solution -「洛谷 P6577」「模板」二分图最大权完美匹配

    \(\mathcal{Description}\)   Link.   给定二分图 \(G=(V=X\cup Y,E)\),\(|X|=|Y|=n\),边 \((u,v)\in E\) 有权 \(w( ...

  7. 二分图学习记 之 KM算法 二分图最大权完美匹配。

    前置知识 :匈牙利算法 首先有这样一张图,求这张图的最大权完美匹配. 当然如果你不想看这些渣图的话,您可以转到 洛谷 运动员最佳匹配问题 下面我来强行解释一下KM算法 左边一群妹子找汉子,但是每个妹子 ...

  8. uva 1411 Ants (权值和最小的完美匹配---KM算法)

    uva 1411 Ants Description Young naturalist Bill studies ants in school. His ants feed on plant-louse ...

  9. hdu 3722 二分图 最优完备匹配 KM算法

    这题只要想到是最优完备匹配就行了: 题意:给出n个字符串,若两两相连,将前一个反置添加到后一个后面,相连的值为两个字串从头开始相等的字符个数: 问如何匹配得出最大值: 思路:建图,套模板. 代码: # ...

随机推荐

  1. windows密码长度最小值改不了

    控制台输入gpedit.msc或者在“开始→控制面板→管理工具→本地安全策略→账户策略→密码策略→密码长度最小值”中修改不了,是灰色的,不让修改 用命令行可以修改开始-->运行-->输入& ...

  2. php服务端接收post的json数据

    最近用到ext与PHP交互,ext把json数据post给PHP,但在PHP里面$_post获取不到,$_REQUEST也获取不到,但是通过firedebug看到的请求信息确实是把JSON数据post ...

  3. ASP.NET Web API 2 框架揭秘

    这不是一本传统意义上的入门书籍 任何 —本书都具有对应的受众群体,所以我不得不将这句话放在最前面,并且希望所有 打算购买此书的读者能够看到.如果你之前对As氵NET W山API(或者AsPNET MⅤ ...

  4. Java报表之JFreeChart

    一.JFreeChart简介 JFreeChart是JAVA平台上的一个开放的图表绘制类库.它完全使用JAVA语言编写,是为applications,servlets以及JSP等使用所设计. JFre ...

  5. el-select,选择一行,取值行的对象.

      <el-select v-model="set_invoice_form.InvoiceType" placeholder="请选择" :disabl ...

  6. Android利用Socket与硬件通信之智能家居APP

    前几天做一个智能家居APP,硬件段使用的是ESP8266WIFI模块,其实不管是WIFI模块还是蓝牙,通信都是同样一个道理,获取IP和端口来进行通信. 我是通过XCOM v2.0 发送信息,移动端接收 ...

  7. 激活eclipse自动提示功能

    eclipse设置: Window->Preferences->Java->Editor->Content Assist

  8. Linux上用mvn安装node.js

    Linux上用mvn安装node.js 上一篇blog简略的讲了ubuntu系统的安装,接下来讲讲Ubuntu上的基于node.js的web开发环境的搭建. Node在快速构建网络服务有着极大的优势, ...

  9. jstat查看JVM的GC情况

    jps(Java Virtual Machine Process Status Tool)是JDK 1.5提供的一个显示当前所有java进程pid的命令,简单实用,非常适合在linux/unix平台上 ...

  10. SPOJ COT2 Count on a tree II (树上莫队,倍增算法求LCA)

    题意:给一个树图,每个点的点权(比如颜色编号),m个询问,每个询问是一个区间[a,b],图中两点之间唯一路径上有多少个不同点权(即多少种颜色).n<40000,m<100000. 思路:无 ...