KM算法(二分图的最佳完美匹配)
KM算法大概过程:
(1)初始化Lx数组为该boy的一条权值最大的出边。初始化Ly数组为 0。
(2)对于每个boy,用DFS为其找到一个girl对象,顺路记录下S和T集,并更新每个girl的slack值。若不能为其找到对象,则转3。
(3)找出非T集合的girl的最小slack值为d,更新S集中的boy和T集中的girl,并且顺路更新非T集中的slack值。对于那个失败的boy继续第2步。
简括之,就是在保持当前权和最高的情况下,尽量为每个boy找到权更大的边。找的过程就是DFS过程,标记出S和T集是为了保证权和最大,因为只要帮S中任意一个boy另找一个女对象,为这个boy的此次脱单之路告终。
DFS的要完成的任务:
(1)标记S和T集。
(2)更新每个girl的slack值为最小。
模板还是必须的,带满了注释,改自kuangbin的模板。
/* KM算法:复杂度O(nx*nx*ny)
* 完全二分图求最大权匹配(必须为所有boy找到对象,且boy数量必须<=girl数量)
* 若求最小权匹配,可将权值取相反数,结果取相反数
* 点的编号从1开始。
* 以男女模型出现比较直观。
*/
int nx, ny; //两边的点数,x为男,y为女。
int g[N][N]; //二分图描述,g[x][y]表示边权。
int girl[N], Lx[N], Ly[N]; //girl[i]记录i的匹配成功对象,男女的顶标
int slack[N]; //为了优化用的,连接到对应girl的松弛值。
bool S[N], T[N]; //匈牙利树的节点集合,S为男,T为女。 bool DFS(int x) // x一定是boy
{
S[x]=true;
for(int i=; i<=ny; i++) //枚举girl
{
if(T[i]) continue;
int tmp=Lx[x]+Ly[i]-g[x][i];
if( tmp== )
{
T[i]=true;
//为第i个girl的男对象另找女对象
if(girl[i]==- || DFS(girl[i]))
{
girl[i]=x; //记录匹配的boy
return true;
}
}
else if(slack[i]>tmp) //顺便更新下slack
slack[i]=tmp;
}
return false;
} int KM()
{
memset(girl, -, sizeof(girl));
memset(Ly, , sizeof(Ly));
for(int i=; i<=nx; i++) //初始化两个L数组分别为-INF和0
{
Lx[i] = -INF;
for(int j=; j<=ny; j++)
if(g[i][j]>Lx[i]) Lx[i]=g[i][j];
}
for(int j=; j<=nx; j++) //枚举boy
{
for(int i=; i<=ny; i++) //初始slack为无穷。slack只需要记录girl的。
slack[i]=INF;
while(true) //无限循环,直到帮boy[j]找到对象
{
memset(S, , sizeof(S));
memset(T, , sizeof(T));
if( DFS(j) ) break; //直接就找到对象了,搞定。
int d=INF;
for(int i=; i<=ny; i++) //根据不在匈牙利树上的girl的slack值找到最小值d
if(!T[i] && d>slack[i])
d=slack[i];
for(int i=; i<=nx; i++) //所有匈牙利树上的boy更新lx值
if(S[i]) Lx[i]-=d;
for(int i=; i<=ny; i++) //树上的girl加d,不在树上的girl的slack减d。
{
if(T[i]) Ly[i]+=d; //这是为了让等式仍然成立
else slack[i]-=d;
}
}
}
int ans=;
for(int i=; i<=ny; i++) //累计匹配边的权和
if(girl[i]>) ans+=g[girl[i]][i];
return ans;
}
KM算法
KM算法(二分图的最佳完美匹配)的更多相关文章
- 二分图学习记 之 KM算法 二分图最大权完美匹配。
前置知识 :匈牙利算法 首先有这样一张图,求这张图的最大权完美匹配. 当然如果你不想看这些渣图的话,您可以转到 洛谷 运动员最佳匹配问题 下面我来强行解释一下KM算法 左边一群妹子找汉子,但是每个妹子 ...
- hdu1533 Going Home km算法解决最小权完美匹配
Going Home Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- poj3565 Ants km算法求最小权完美匹配,浮点权值
/** 题目:poj3565 Ants km算法求最小权完美匹配,浮点权值. 链接:http://poj.org/problem?id=3565 题意:给定n个白点的二维坐标,n个黑点的二维坐标. 求 ...
- HDU 2255 KM算法 二分图最大权值匹配
奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Subm ...
- UVa1349 Optimal Bus Route Design(二分图最佳完美匹配)
UVA - 1349 Optimal Bus Route Design Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & ...
- 【模板】二分图最大权完美匹配KM算法
hdu2255模板题 KM是什么意思,详见百度百科. 总之知道它可以求二分图最大权完美匹配就可以了,时间复杂度为O(n^3). 给张图. 二分图有了边权,求最大匹配下的最大权值. 所以该怎么做呢?对啊 ...
- 【二分图最大权完美匹配】【KM算法】【转】
[文章详解出处]https://www.cnblogs.com/wenruo/p/5264235.html KM算法是用来求二分图最大权完美匹配的.[也就算之前的匈牙利算法求二分最大匹配的变种??] ...
- 二分图最大权完美匹配KM算法
KM算法二分图 KM求得二分图与普通二分图的不同之处在于:此二分图的每条边(男生女生)上都附了权值(好感度).然后,求怎样完美匹配使得权值之和最大. 这,不止一般的麻烦啊. 可以通过一个期望值来求. ...
- 【模板】二分图最大权完美匹配(KM算法)/洛谷P6577
题目链接 https://www.luogu.com.cn/problem/P6577 题目大意 给定一个二分图,其左右点的个数各为 \(n\),带权边数为 \(m\),保证存在完美匹配. 求一种完美 ...
随机推荐
- POJ 2549
Sumsets Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 8235 Accepted: 2260 Descripti ...
- centOS学习part1:操作系统安装
0 linux作为服务器的主要操作系统,在处理速度以及安全性上都要优于windows,虽然需要很多命令要记,但是一般常用的命令不多,用多了就熟悉了,而且现在很多都要图形界面,也降低了学习成本. cen ...
- ADs系列之通用数据解析服务GAS(即将开源)
面对成百上千的生产系统用户操作数据接入落地,你是否厌倦了每次机械编写打包解包的代码?对一次性接入多个数据的时候,还要对不同人联调,费时费力,你是否还会手忙脚乱,忙中不断出错?是否当数据出问题了,用的时 ...
- Linux基础--文件与目录管理
1.目录与路径 1)特殊目录 . 代表此层目录 .. 代表上一层目录 - 代表前一个工作目录 ~ 代表『目前使用者身份』所在的家目录 ~account 代表account这个使用者的 ...
- wordpress编辑器无法切换/输入
出现问题:“可视化”和“文本”无法切换,编辑区也无法输入文字 解决方法: 打开wp-config.php,在 require_once(ABSPATH . 'wp-settings.php'); 后面 ...
- linux shell 命令学习(2) paste - merge lines of files
paste - merge lines of files 命令格式: paste [OPTION] ... [FILE] ... 说明: 输出每个文件的对应行组合而成的行,中间用tab分开,如果没有F ...
- UML系列02之 UML类图(2)
UML类图的几种关系 在UML类图中,关系可以分为4种: 泛化, 实现, 关联 和 依赖.1. 泛化 -- 表示"类与类之间的继承关系".2. 实现 -- 表示"类与接口 ...
- 293. Flip Game
题目: You are playing the following Flip Game with your friend: Given a string that contains only thes ...
- USACO Section 4.2: The Perfect Stall
这题关键就在将题转换成最大流模板题.首先有一个原始点,N个cow个点, M个barn点和一个终点,原始点到cow点和barn点到终点的流都为1,而cow对应的barn就是cow点到对应barn点的流, ...
- Android 代码监控apk安装,卸载,替换
public class GetBroadcast extends BroadcastReceiver { private static GetBroadcast mReceiver = new Ge ...