HDU 2255 奔小康赚大钱 KM算法的简单解释
KM算法一般用来寻找二分图的最优匹配。
步骤:
1.初始化可行标杆
2.对新加入的点用匈牙利算法进行判断
3.若无法加入新编,修改可行标杆
4.重复2.3操作直到找到相等子图的完全匹配。
各步骤简述:
1.根据二分图建立2个可行标杆;
lx为x的可行标杆,初始化lx[i]为与i点相连的最大边
ly为y的可行标杆,初始化为0.
可行性的判断条件应为lx[x]+ly[y] >= Map[x][y]。
2.对于新加入的点用匈牙利算法经行判断,确定改点能否加入旧子图中,形成新子图。
对于该加入的点有两种可能:
2.1.找到某个y点,该y点为被连接,则与该点相连,并符合条件
2.2找到某个y点,该y点已经被某x1点所连接,则对x1点经行深搜,若x1可以找到新的连接点,则修改x1的连接路径,并使x点与y点相连。
3.如果发现无法再向已有的相等子图中加入边,则证明不再有lx[x]+ly[y]==Map[x][y]成立,那么我们对x和y的可行标杆经行修改。
当找不到增广路径时,对于搜索过的路径上的XY点,设该路径上的X顶点集为S,Y顶点集为T,对所有在S中的点xi及不在T中的点yj,计算d=min{(L(xi)+L(yj)-weight(xiyj))},从S集中的X标杆中减去d,并将其加入到T集中的Y的标杆中,由于S集中的X标杆减少了,而不在T中的Y标杆不变,相当于这两个集合中的lx(x)+ly(y)变小了,也就是,lx[x]+ly[y]将变小,便有可能有lx[x]+ly[y]==Map[x][y]成立,即可能会加入新的边。
4.重复2.3过程,知道找到完备相等子图为止。
时间复杂度:优化后大概为O(n^3);
代码:
#include<cstdio>
#include<stdio.h>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#define INF 0x3f3f3f3f
#define MAX 1005
#define mod 1000000007 using namespace std; int visx[MAX],visy[MAX],lx[MAX],ly[MAX],linker[MAX],slack[MAX],Map[MAX][MAX],n; bool DFS(int x)
{
visx[x]=;
for(int y=;y<=n;y++)
{
if(visy[y])
continue;
int tmp=lx[x]+ly[y]-Map[x][y];
if(tmp==)
{
visy[y]=;
if(linker[y]==- || DFS(linker[y]))
{
linker[y]=x;
return true;
}
}
else
{
slack[y]=min(slack[y],tmp);
}
}
return false;
} int KM()
{
int i,j;
memset(ly,,sizeof(ly));//初始化可行标杆ly
memset(linker,-,sizeof(linker));
for(i=; i<=n; i++)//初始化可行标杆lx
{
lx[i]=-INF;
for(j=; j<=n; j++)
lx[i]=max(lx[i],Map[i][j]);
} for(int x=; x<=n; x++)
{
for(i=; i<=n; i++)
slack[i]=INF;
while()
{
memset(visx,,sizeof(visx));
memset(visy,,sizeof(visy));
if(DFS(x))//若可加入直接跳出
break;
int d=INF;
for(i=; i<=n; i++)
{
if(!visy[i])
d=min(slack[i],d);//否则根据贪心的思想,找到最小的可行标杆修改值
}
for(i=; i<=n; i++)//修改lx标杆
{
if(visx[i])
lx[i]-=d;
}
for(i=; i<=n; i++)//修改ly标杆
{
if(visy[i])
ly[i]+=d;
else
slack[i]-=d;//slack由lx[x]+ly[y]-Map[x][y]而来;ly中未标记过的值不变,lx中已标记过的值减少,则slack应减少
}
}
}
int ans=;
for(i=;i<=n;i++)
{
ans+=Map[linker[i]][i];
}
return ans;
} int main()
{
while(scanf("%d",&n)!=EOF)
{
for(int i=; i<=n; i++)
{
for(int j=; j<=n; j++)
scanf("%d",&Map[i][j]);
} int ans=KM();
printf("%d\n",ans);
}
return ;
}
HDU 2255 奔小康赚大钱 KM算法的简单解释的更多相关文章
- hdu 2255 奔小康赚大钱--KM算法模板
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2255 题意:有N个人跟N个房子,每个人跟房子都有一定的距离,现在要让这N个人全部回到N个房子里面去,要 ...
- hdu 2255奔小康赚大钱 KM算法模板
题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=2255 一,KM算法:(借助这个题写一下个人对km的理解与km模板) KM算法主要是用来求解图的最优匹 ...
- HDU - 2255 奔小康赚大钱 KM算法 模板题
HDU - 2255 题意: 分配n所房子给n个家庭,不同家庭对一所房子所需缴纳的钱是不一样的,问你应当怎么分配房子,使得最后收到的钱最多. 思路: KM算法裸题.上模板 #include <i ...
- hdu 2255 奔小康赚大钱 KM算法
看到这么奇葩的题目名我笑了,后来这么一个裸的KM调了2小时我哭了…… 这是个裸的KM算法,也没什么多说的,主要是注意多组数据时,每次都要把各种数组清空啊,赋值啊什么的,反正比较麻烦.至于为什么调了2小 ...
- HDU 2255 奔小康赚大钱 KM算法题解
KM算法求的是完备匹配下的最大权匹配,是Hungary算法的进一步,由于Hungary算法是最大匹配的算法,不带权. 经典算法,想不出来的了,要參考别人的.然后消化吸收吧. 由于真的非常复杂的算法. ...
- hdu 2255 奔小康赚大钱 (KM)
奔小康赚大钱Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- HDU 2255 奔小康赚大钱 KM裸题
#include <stdio.h> #include <string.h> #define M 310 #define inf 0x3f3f3f3f int n,nx,ny; ...
- 二分图最大权匹配问题&&KM算法讲解 && HDU 2255 奔小康赚大钱
作者:logosG 链接:https://www.cnblogs.com/logosG/p/logos.html (讲解的KM算法,特别厉害!!!) KM算法: 现在我们来考虑另外一个问题:如果每个员 ...
- HDU 2255 奔小康赚大钱(带权二分图最大匹配)
HDU 2255 奔小康赚大钱(带权二分图最大匹配) Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子. 这可是一件大事,关系到人民的住房问题啊 ...
随机推荐
- STL学习:STL库vector、string、set、map用法
本文仅介绍了如何使用它们常用的方法. vector 1.可随机访问,可在尾部插入元素:2.内存自动管理:3.头文件#include <vector> 1.创建vector对象 一维: (1 ...
- DX shader根据顶点设置颜色
matrix ViewProjMatrix; vector Blue = {0.0f, 0.0f, 1.0f, 0.0f}; struct VS_INPUT { vector position : P ...
- solr定时增量索引
当数据库的数据发生改变的时候,我们不想手动的去重新添加数据库的数据导solr索引库中,所以用到定时添加索引.增删改的数据.现在写的这些都是基于我之前做的一步步到这来的. 将solr/dist下的sol ...
- 关于Mongdb的java的CRUD操作
package mongodb; import java.net.UnknownHostException;import java.util.List; import com.mongodb.Basi ...
- Xcode8中添加SnapKit框架报错,编译失败
既然SnapKit的作者说SnapKit已经支持Swift3.0了,那么我们就先来适配SnapKit,首先用Xcode8新建一个空项目,利用Cocoapods导入SnapKit. Podfile 打 ...
- 2015 Multi-University Training Contest 9
1001 Expression 式子不好推啊.见官方题解. 式子知道就方便了.处理好组合数和阶乘. 按区间长度从小到大递推完就好. # include <iostream> # inclu ...
- offset()值不准问题
本来应该只需获取含图片的div的offset(),然后将标签div的坐标设置好即可,但是不知为何越靠后的div的offset().top越不正常,跟标准值偏离的越来越大. 即使你在$(document ...
- Asynchronous JS: Callbacks, Listeners, Control Flow Libs and Promises
非常好的文章,讲javascript 的异步编程的. ------------------------------------------------------------------------- ...
- CSS3的box-sizing属性
盒模型的宽度,在 IE5.x 以及 Quirks 模式的 IE6/7 中,将 border 与 padding 都包含在 width 之内 W3C标准中的盒模型宽度为内容宽度,不包括内边距paddin ...
- Python Cookbook - 1 - 数据结构和算法
1 序列解压:通过*来通配 *a, b = somelist, first, *mid, last = somelist, a, *b = somelist 2 使用双向队列: from col ...