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

  1. hdu 2255 奔小康赚大钱--KM算法模板

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2255 题意:有N个人跟N个房子,每个人跟房子都有一定的距离,现在要让这N个人全部回到N个房子里面去,要 ...

  2. hdu 2255奔小康赚大钱 KM算法模板

    题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=2255 一,KM算法:(借助这个题写一下个人对km的理解与km模板) KM算法主要是用来求解图的最优匹 ...

  3. HDU - 2255 奔小康赚大钱 KM算法 模板题

    HDU - 2255 题意: 分配n所房子给n个家庭,不同家庭对一所房子所需缴纳的钱是不一样的,问你应当怎么分配房子,使得最后收到的钱最多. 思路: KM算法裸题.上模板 #include <i ...

  4. hdu 2255 奔小康赚大钱 KM算法

    看到这么奇葩的题目名我笑了,后来这么一个裸的KM调了2小时我哭了…… 这是个裸的KM算法,也没什么多说的,主要是注意多组数据时,每次都要把各种数组清空啊,赋值啊什么的,反正比较麻烦.至于为什么调了2小 ...

  5. HDU 2255 奔小康赚大钱 KM算法题解

    KM算法求的是完备匹配下的最大权匹配,是Hungary算法的进一步,由于Hungary算法是最大匹配的算法,不带权. 经典算法,想不出来的了,要參考别人的.然后消化吸收吧. 由于真的非常复杂的算法. ...

  6. hdu 2255 奔小康赚大钱 (KM)

    奔小康赚大钱Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  7. HDU 2255 奔小康赚大钱 KM裸题

    #include <stdio.h> #include <string.h> #define M 310 #define inf 0x3f3f3f3f int n,nx,ny; ...

  8. 二分图最大权匹配问题&&KM算法讲解 && HDU 2255 奔小康赚大钱

    作者:logosG 链接:https://www.cnblogs.com/logosG/p/logos.html (讲解的KM算法,特别厉害!!!) KM算法: 现在我们来考虑另外一个问题:如果每个员 ...

  9. HDU 2255 奔小康赚大钱(带权二分图最大匹配)

    HDU 2255 奔小康赚大钱(带权二分图最大匹配) Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子. 这可是一件大事,关系到人民的住房问题啊 ...

随机推荐

  1. [SOJ]1753 解码

    1753. 解码 Constraints Time Limit: 1 secs, Memory Limit: 32 MB Description ZX是另一头04级的牛,他现在在UPen.他跟LLK经 ...

  2. MVC3+EF4.1学习系列(七)-----EF并发的处理

    看这篇文章之前 推荐园子里的 这个文章已经有介绍了 而且写的很好~~ 可以先看下他的 再看我的 并发 1.悲观并发 简单的说 就是一个用户访问一条数据时 则把这个数据变为只读属性  把该数据变为独占 ...

  3. Program Files 与Program Files (x86)

    在64位系统下,为了更好的兼容32位程序,在安装一些32位程序(注意某些程序他就是32位的),会默认扔到program files(x86)这个文件夹下,而一些64位的程序,或程序本身没有位数区别的, ...

  4. ***C - I love sneakers!(动态规划,分组背包)

    C - I love sneakers! Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64 ...

  5. Nginx 安装(CentOS )

    一.安装编译工具及库文件 yum -y install make zlib zlib-devel gcc-c++ libtool openssl openssl-devel 二.首先要安装 PCRE ...

  6. html5 --基础笔记2

    1.autocomplete 可以给表单本身(不是fieldset)设置属性来禁用整个表单的自动完成功能 <form id="" method="" au ...

  7. NEU OJ 1644 Median I

    优先级队列 #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> ...

  8. Spring的后置处理器BeanPostProcessor

    一.BeanPostProcessor接口的作用 如果我们需要在Spring容器完成Bean的实例化.配置和其他的初始化前后添加一些自己的逻辑处理,我们就可以定义一个或者多个BeanPostProce ...

  9. c语言-经验之谈

    如果你是一个大牛,那就直接忽略这里. 如果你是一个新手,请继续向下看. 在自学计算机的路上真的很悲惨,如果你是在学校里面学习还算比较幸运. 针对编程来说,在学校里面学习的只是学会了语言,而很少有人学会 ...

  10. Chapter 1 First Sight——34

    "Was that the boy I sat next to in Biology?" I asked artlessly. 你是生物课坐在我旁边的男生吗?我天真烂漫的问道. & ...